From 5a8d1ffdbaed72a2f4b9ee79316f93be070fc1e0 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 30 May 2018 12:08:03 +0200 Subject: [PATCH 01/26] Prototype for exporting estimated remaining time into gcode for default and silent mode --- lib/Slic3r/GUI/Plater.pm | 6 +- xs/src/libslic3r/GCode.cpp | 36 ++- xs/src/libslic3r/GCode.hpp | 7 +- xs/src/libslic3r/GCodeTimeEstimator.cpp | 397 ++++++++++++++++++------ xs/src/libslic3r/GCodeTimeEstimator.hpp | 48 ++- xs/src/libslic3r/Print.hpp | 3 +- xs/xsp/Print.xsp | 6 +- 7 files changed, 377 insertions(+), 126 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 8d4a1a2691..911c07cbf7 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -472,7 +472,8 @@ sub new { fil_mm3 => L("Used Filament (mm³)"), fil_g => L("Used Filament (g)"), cost => L("Cost"), - time => L("Estimated printing time"), + default_time => L("Estimated printing time (default mode)"), + silent_time => L("Estimated printing time (silent mode)"), ); while (my $field = shift @info) { my $label = shift @info; @@ -1542,7 +1543,8 @@ sub on_export_completed { $self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost)); $self->{"print_info_fil_g"}->SetLabel(sprintf("%.2f" , $self->{print}->total_weight)); $self->{"print_info_fil_mm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume)); - $self->{"print_info_time"}->SetLabel($self->{print}->estimated_print_time); + $self->{"print_info_default_time"}->SetLabel($self->{print}->estimated_default_print_time); + $self->{"print_info_silent_time"}->SetLabel($self->{print}->estimated_silent_print_time); $self->{"print_info_fil_m"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament / 1000)); $self->{"print_info_box_show"}->(1); diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index b581b3e76a..28c15e2fd7 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -374,6 +374,9 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ throw std::runtime_error(std::string("G-code export to ") + path + " failed\nIs the disk full?\n"); } fclose(file); + + GCodeTimeEstimator::post_process_elapsed_times(path_tmp, m_default_time_estimator.get_time(), m_silent_time_estimator.get_time()); + if (! this->m_placeholder_parser_failed_templates.empty()) { // G-code export proceeded, but some of the PlaceholderParser substitutions failed. std::string msg = std::string("G-code export to ") + path + " failed due to invalid custom G-code sections:\n\n"; @@ -403,9 +406,11 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) { PROFILE_FUNC(); - // resets time estimator - m_time_estimator.reset(); - m_time_estimator.set_dialect(print.config.gcode_flavor); + // resets time estimators + m_default_time_estimator.reset(); + m_default_time_estimator.set_dialect(print.config.gcode_flavor); + m_silent_time_estimator.reset(); + m_silent_time_estimator.set_dialect(print.config.gcode_flavor); // resets analyzer m_analyzer.reset(); @@ -596,6 +601,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) _writeln(file, buf); } + // before start gcode time estimation + _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); + _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); + // Write the custom start G-code _writeln(file, start_gcode); // Process filament-specific gcode in extruder order. @@ -800,13 +809,17 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) for (const std::string &end_gcode : print.config.end_filament_gcode.values) _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()), &config)); } + // before end gcode time estimation + _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); + _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); _writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id(), &config)); } _write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% _write(file, m_writer.postamble()); // calculates estimated printing time - m_time_estimator.calculate_time(); + m_default_time_estimator.calculate_time(); + m_silent_time_estimator.calculate_time(); // Get filament stats. print.filament_stats.clear(); @@ -814,7 +827,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) print.total_extruded_volume = 0.; print.total_weight = 0.; print.total_cost = 0.; - print.estimated_print_time = m_time_estimator.get_time_hms(); + print.estimated_default_print_time = m_default_time_estimator.get_time_dhms(); + print.estimated_silent_print_time = m_silent_time_estimator.get_time_dhms(); for (const Extruder &extruder : m_writer.extruders()) { double used_filament = extruder.used_filament(); double extruded_volume = extruder.extruded_volume(); @@ -834,7 +848,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) print.total_extruded_volume = print.total_extruded_volume + extruded_volume; } _write_format(file, "; total filament cost = %.1lf\n", print.total_cost); - _write_format(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms().c_str()); + _write_format(file, "; estimated printing time (default mode) = %s\n", m_default_time_estimator.get_time_dhms().c_str()); + _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); // Append full config. _write(file, "\n"); @@ -1399,8 +1414,12 @@ void GCode::process_layer( if (m_pressure_equalizer) gcode = m_pressure_equalizer->process(gcode.c_str(), false); // printf("G-code after filter:\n%s\n", out.c_str()); - + _write(file, gcode); + + // after layer time estimation + _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); + _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); } void GCode::apply_print_config(const PrintConfig &print_config) @@ -2059,7 +2078,8 @@ void GCode::_write(FILE* file, const char *what) // writes string to file fwrite(gcode, 1, ::strlen(gcode), file); // updates time estimator and gcode lines vector - m_time_estimator.add_gcode_block(gcode); + m_default_time_estimator.add_gcode_block(gcode); + m_silent_time_estimator.add_gcode_block(gcode); } } diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index d028e90aac..b938604ef6 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -133,6 +133,8 @@ public: m_last_height(GCodeAnalyzer::Default_Height), m_brim_done(false), m_second_layer_things_done(false), + m_default_time_estimator(GCodeTimeEstimator::Default), + m_silent_time_estimator(GCodeTimeEstimator::Silent), m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())) {} ~GCode() {} @@ -289,8 +291,9 @@ protected: // Index of a last object copy extruded. std::pair m_last_obj_copy; - // Time estimator - GCodeTimeEstimator m_time_estimator; + // Time estimators + GCodeTimeEstimator m_default_time_estimator; + GCodeTimeEstimator m_silent_time_estimator; // Analyzer GCodeAnalyzer m_analyzer; diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 176159ff56..553ddba083 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -4,9 +4,14 @@ #include +#include +#include +#include + static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float MILLISEC_TO_SEC = 0.001f; static const float INCHES_TO_MM = 25.4f; + static const float DEFAULT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 static const float DEFAULT_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 @@ -17,8 +22,31 @@ static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Conf static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent +static const float SILENT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) +static const float SILENT_ACCELERATION = 1250.0f; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full +static const float SILENT_RETRACT_ACCELERATION = 1250.0f; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full +static const float SILENT_AXIS_MAX_FEEDRATE[] = { 200.0f, 200.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full +static const float SILENT_AXIS_MAX_ACCELERATION[] = { 1000.0f, 1000.0f, 200.0f, 5000.0f }; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full +static const float SILENT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.4f, 2.5f }; // from Prusa Firmware (Configuration.h) +static const float SILENT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +static const float SILENT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +static const float SILENT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent + static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; +static const std::string ELAPSED_TIME_TAG_DEFAULT = ";_ELAPSED_TIME_DEFAULT: "; +static const std::string ELAPSED_TIME_TAG_SILENT = ";_ELAPSED_TIME_SILENT: "; + +#define REMAINING_TIME_USE_SINGLE_GCODE_COMMAND 1 +#if REMAINING_TIME_USE_SINGLE_GCODE_COMMAND +static const std::string REMAINING_TIME_CMD = "M998"; +#else +static const std::string REMAINING_TIME_CMD_DEFAULT = "M998"; +static const std::string REMAINING_TIME_CMD_SILENT = "M999"; +#endif // REMAINING_TIME_USE_SINGLE_GCODE_COMMAND + +static const std::string REMAINING_TIME_COMMENT = " ; estimated remaining time"; + #if ENABLE_MOVE_STATS static const std::string MOVE_TYPE_STR[Slic3r::GCodeTimeEstimator::Block::Num_Types] = { @@ -73,6 +101,11 @@ namespace Slic3r { return ::sqrt(value); } + GCodeTimeEstimator::Block::Block() + : st_synchronized(false) + { + } + float GCodeTimeEstimator::Block::move_length() const { float length = ::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); @@ -159,63 +192,13 @@ namespace Slic3r { } #endif // ENABLE_MOVE_STATS - GCodeTimeEstimator::GCodeTimeEstimator() + GCodeTimeEstimator::GCodeTimeEstimator(EMode mode) + : _mode(mode) { reset(); set_default(); } - void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode) - { - reset(); - - _parser.parse_buffer(gcode, - [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) - { this->_process_gcode_line(reader, line); }); - - _calculate_time(); - -#if ENABLE_MOVE_STATS - _log_moves_stats(); -#endif // ENABLE_MOVE_STATS - - _reset_blocks(); - _reset(); - } - - void GCodeTimeEstimator::calculate_time_from_file(const std::string& file) - { - reset(); - - _parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); - _calculate_time(); - -#if ENABLE_MOVE_STATS - _log_moves_stats(); -#endif // ENABLE_MOVE_STATS - - _reset_blocks(); - _reset(); - } - - void GCodeTimeEstimator::calculate_time_from_lines(const std::vector& gcode_lines) - { - reset(); - - auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) - { this->_process_gcode_line(reader, line); }; - for (const std::string& line : gcode_lines) - _parser.parse_line(line, action); - _calculate_time(); - -#if ENABLE_MOVE_STATS - _log_moves_stats(); -#endif // ENABLE_MOVE_STATS - - _reset_blocks(); - _reset(); - } - void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line) { PROFILE_FUNC(); @@ -239,14 +222,157 @@ namespace Slic3r { void GCodeTimeEstimator::calculate_time() { PROFILE_FUNC(); + _reset_time(); + _set_blocks_st_synchronize(false); _calculate_time(); #if ENABLE_MOVE_STATS _log_moves_stats(); #endif // ENABLE_MOVE_STATS + } - _reset_blocks(); - _reset(); + void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode) + { + reset(); + + _parser.parse_buffer(gcode, + [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }); + + _calculate_time(); + +#if ENABLE_MOVE_STATS + _log_moves_stats(); +#endif // ENABLE_MOVE_STATS + } + + void GCodeTimeEstimator::calculate_time_from_file(const std::string& file) + { + reset(); + + _parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + _calculate_time(); + +#if ENABLE_MOVE_STATS + _log_moves_stats(); +#endif // ENABLE_MOVE_STATS + } + + void GCodeTimeEstimator::calculate_time_from_lines(const std::vector& gcode_lines) + { + reset(); + + auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }; + for (const std::string& line : gcode_lines) + _parser.parse_line(line, action); + _calculate_time(); + +#if ENABLE_MOVE_STATS + _log_moves_stats(); +#endif // ENABLE_MOVE_STATS + } + + std::string GCodeTimeEstimator::get_elapsed_time_string() + { + calculate_time(); + switch (_mode) + { + default: + case Default: + return ELAPSED_TIME_TAG_DEFAULT + std::to_string(get_time()) + "\n"; + case Silent: + return ELAPSED_TIME_TAG_SILENT + std::to_string(get_time()) + "\n"; + } + } + + bool GCodeTimeEstimator::post_process_elapsed_times(const std::string& filename, float default_time, float silent_time) + { + boost::nowide::ifstream in(filename); + if (!in.good()) + throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for reading.\n")); + + std::string path_tmp = filename + ".times"; + + FILE* out = boost::nowide::fopen(path_tmp.c_str(), "wb"); + if (out == nullptr) + throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for writing.\n")); + + std::string line; + while (std::getline(in, line)) + { + if (!in.good()) + { + fclose(out); + throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n")); + } + +#if REMAINING_TIME_USE_SINGLE_GCODE_COMMAND + // this function expects elapsed time for default and silent mode to be into two consecutive lines inside the gcode + if (boost::contains(line, ELAPSED_TIME_TAG_DEFAULT)) + { + std::string default_elapsed_time_str = line.substr(ELAPSED_TIME_TAG_DEFAULT.length()); + line = REMAINING_TIME_CMD + " D:" + _get_time_dhms(default_time - (float)atof(default_elapsed_time_str.c_str())); + + std::string next_line; + std::getline(in, next_line); + if (!in.good()) + { + fclose(out); + throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n")); + } + + if (boost::contains(next_line, ELAPSED_TIME_TAG_SILENT)) + { + std::string silent_elapsed_time_str = next_line.substr(ELAPSED_TIME_TAG_SILENT.length()); + line += " S:" + _get_time_dhms(silent_time - (float)atof(silent_elapsed_time_str.c_str())) + REMAINING_TIME_COMMENT; + } + else + // found horphaned default elapsed time, skip the remaining time line output + line = next_line; + } + else if (boost::contains(line, ELAPSED_TIME_TAG_SILENT)) + // found horphaned silent elapsed time, skip the remaining time line output + continue; +#else + bool processed = false; + if (boost::contains(line, ELAPSED_TIME_TAG_DEFAULT)) + { + std::string elapsed_time_str = line.substr(ELAPSED_TIME_TAG_DEFAULT.length()); + line = REMAINING_TIME_CMD_DEFAULT + " " + _get_time_dhms(default_time - (float)atof(elapsed_time_str.c_str())); + processed = true; + } + else if (boost::contains(line, ELAPSED_TIME_TAG_SILENT)) + { + std::string elapsed_time_str = line.substr(ELAPSED_TIME_TAG_SILENT.length()); + line = REMAINING_TIME_CMD_SILENT + " " + _get_time_dhms(silent_time - (float)atof(elapsed_time_str.c_str())); + processed = true; + } + + if (processed) + line += REMAINING_TIME_COMMENT; +#endif // REMAINING_TIME_USE_SINGLE_GCODE_COMMAND + + line += "\n"; + fwrite((const void*)line.c_str(), 1, line.length(), out); + if (ferror(out)) + { + in.close(); + fclose(out); + boost::nowide::remove(path_tmp.c_str()); + throw std::runtime_error(std::string("Remaining times estimation failed.\nIs the disk full?\n")); + } + } + + fclose(out); + in.close(); + + boost::nowide::remove(filename.c_str()); + if (boost::nowide::rename(path_tmp.c_str(), filename.c_str()) != 0) + throw std::runtime_error(std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + filename + '\n' + + "Is " + path_tmp + " locked?" + '\n'); + + return true; } void GCodeTimeEstimator::set_axis_position(EAxis axis, float position) @@ -411,6 +537,66 @@ namespace Slic3r { set_global_positioning_type(Absolute); set_e_local_positioning_type(Absolute); + switch (_mode) + { + default: + case Default: + { + _set_default_as_default(); + break; + } + case Silent: + { + _set_default_as_silent(); + break; + } + } + } + + void GCodeTimeEstimator::reset() + { + _reset_time(); +#if ENABLE_MOVE_STATS + _moves_stats.clear(); +#endif // ENABLE_MOVE_STATS + _reset_blocks(); + _reset(); + } + + float GCodeTimeEstimator::get_time() const + { + return _time; + } + + std::string GCodeTimeEstimator::get_time_dhms() const + { + return _get_time_dhms(get_time()); + } + + void GCodeTimeEstimator::_reset() + { + _curr.reset(); + _prev.reset(); + + set_axis_position(X, 0.0f); + set_axis_position(Y, 0.0f); + set_axis_position(Z, 0.0f); + + set_additional_time(0.0f); + } + + void GCodeTimeEstimator::_reset_time() + { + _time = 0.0f; + } + + void GCodeTimeEstimator::_reset_blocks() + { + _blocks.clear(); + } + + void GCodeTimeEstimator::_set_default_as_default() + { set_feedrate(DEFAULT_FEEDRATE); set_acceleration(DEFAULT_ACCELERATION); set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION); @@ -427,55 +613,30 @@ namespace Slic3r { } } - void GCodeTimeEstimator::reset() + void GCodeTimeEstimator::_set_default_as_silent() { - _time = 0.0f; -#if ENABLE_MOVE_STATS - _moves_stats.clear(); -#endif // ENABLE_MOVE_STATS - _reset_blocks(); - _reset(); + set_feedrate(SILENT_FEEDRATE); + set_acceleration(SILENT_ACCELERATION); + set_retract_acceleration(SILENT_RETRACT_ACCELERATION); + set_minimum_feedrate(SILENT_MINIMUM_FEEDRATE); + set_minimum_travel_feedrate(SILENT_MINIMUM_TRAVEL_FEEDRATE); + set_extrude_factor_override_percentage(SILENT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE); + + for (unsigned char a = X; a < Num_Axis; ++a) + { + EAxis axis = (EAxis)a; + set_axis_max_feedrate(axis, SILENT_AXIS_MAX_FEEDRATE[a]); + set_axis_max_acceleration(axis, SILENT_AXIS_MAX_ACCELERATION[a]); + set_axis_max_jerk(axis, SILENT_AXIS_MAX_JERK[a]); + } } - float GCodeTimeEstimator::get_time() const + void GCodeTimeEstimator::_set_blocks_st_synchronize(bool state) { - return _time; - } - - std::string GCodeTimeEstimator::get_time_hms() const - { - float timeinsecs = get_time(); - int hours = (int)(timeinsecs / 3600.0f); - timeinsecs -= (float)hours * 3600.0f; - int minutes = (int)(timeinsecs / 60.0f); - timeinsecs -= (float)minutes * 60.0f; - - char buffer[64]; - if (hours > 0) - ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)timeinsecs); - else if (minutes > 0) - ::sprintf(buffer, "%dm %ds", minutes, (int)timeinsecs); - else - ::sprintf(buffer, "%ds", (int)timeinsecs); - - return buffer; - } - - void GCodeTimeEstimator::_reset() - { - _curr.reset(); - _prev.reset(); - - set_axis_position(X, 0.0f); - set_axis_position(Y, 0.0f); - set_axis_position(Z, 0.0f); - - set_additional_time(0.0f); - } - - void GCodeTimeEstimator::_reset_blocks() - { - _blocks.clear(); + for (Block& block : _blocks) + { + block.st_synchronized = state; + } } void GCodeTimeEstimator::_calculate_time() @@ -488,6 +649,9 @@ namespace Slic3r { for (const Block& block : _blocks) { + if (block.st_synchronized) + continue; + #if ENABLE_MOVE_STATS float block_time = 0.0f; block_time += block.acceleration_time(); @@ -1043,7 +1207,7 @@ namespace Slic3r { void GCodeTimeEstimator::_simulate_st_synchronize() { _calculate_time(); - _reset_blocks(); + _set_blocks_st_synchronize(true); } void GCodeTimeEstimator::_forward_pass() @@ -1051,7 +1215,10 @@ namespace Slic3r { if (_blocks.size() > 1) { for (unsigned int i = 0; i < (unsigned int)_blocks.size() - 1; ++i) - { + { + if (_blocks[i].st_synchronized || _blocks[i + 1].st_synchronized) + continue; + _planner_forward_pass_kernel(_blocks[i], _blocks[i + 1]); } } @@ -1063,6 +1230,9 @@ namespace Slic3r { { for (int i = (int)_blocks.size() - 1; i >= 1; --i) { + if (_blocks[i - 1].st_synchronized || _blocks[i].st_synchronized) + continue; + _planner_reverse_pass_kernel(_blocks[i - 1], _blocks[i]); } } @@ -1115,6 +1285,9 @@ namespace Slic3r { for (Block& b : _blocks) { + if (b.st_synchronized) + continue; + curr = next; next = &b; @@ -1144,6 +1317,28 @@ namespace Slic3r { } } + std::string GCodeTimeEstimator::_get_time_dhms(float time_in_secs) + { + int days = (int)(time_in_secs / 86400.0f); + time_in_secs -= (float)days * 86400.0f; + int hours = (int)(time_in_secs / 3600.0f); + time_in_secs -= (float)hours * 3600.0f; + int minutes = (int)(time_in_secs / 60.0f); + time_in_secs -= (float)minutes * 60.0f; + + char buffer[64]; + if (days > 0) + ::sprintf(buffer, "%dd %dh %dm %ds", days, hours, minutes, (int)time_in_secs); + else if (hours > 0) + ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs); + else if (minutes > 0) + ::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs); + else + ::sprintf(buffer, "%ds", (int)time_in_secs); + + return buffer; + } + #if ENABLE_MOVE_STATS void GCodeTimeEstimator::_log_moves_stats() const { diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 8f948abd12..c3fe0f04c9 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -17,6 +17,12 @@ namespace Slic3r { class GCodeTimeEstimator { public: + enum EMode : unsigned char + { + Default, + Silent + }; + enum EUnits : unsigned char { Millimeters, @@ -135,6 +141,10 @@ namespace Slic3r { FeedrateProfile feedrate; Trapezoid trapezoid; + bool st_synchronized; + + Block(); + // Returns the length of the move covered by this block, in mm float move_length() const; @@ -188,18 +198,29 @@ namespace Slic3r { #endif // ENABLE_MOVE_STATS private: + EMode _mode; GCodeReader _parser; State _state; Feedrates _curr; Feedrates _prev; BlocksList _blocks; float _time; // s + #if ENABLE_MOVE_STATS MovesStatsMap _moves_stats; #endif // ENABLE_MOVE_STATS public: - GCodeTimeEstimator(); + explicit GCodeTimeEstimator(EMode mode); + + // Adds the given gcode line + void add_gcode_line(const std::string& gcode_line); + + void add_gcode_block(const char *ptr); + void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); } + + // Calculates the time estimate from the gcode lines added using add_gcode_line() or add_gcode_block() + void calculate_time(); // Calculates the time estimate from the given gcode in string format void calculate_time_from_text(const std::string& gcode); @@ -210,14 +231,12 @@ namespace Slic3r { // Calculates the time estimate from the gcode contained in given list of gcode lines void calculate_time_from_lines(const std::vector& gcode_lines); - // Adds the given gcode line - void add_gcode_line(const std::string& gcode_line); + // Calculates the time estimate from the gcode lines added using add_gcode_line() or add_gcode_block() + // and returns it in a formatted string + std::string get_elapsed_time_string(); - void add_gcode_block(const char *ptr); - void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); } - - // Calculates the time estimate from the gcode lines added using add_gcode_line() - void calculate_time(); + // Converts elapsed time lines, contained in the gcode saved with the given filename, into remaining time commands + static bool post_process_elapsed_times(const std::string& filename, float default_time, float silent_time); // Set current position on the given axis with the given value void set_axis_position(EAxis axis, float position); @@ -275,13 +294,19 @@ namespace Slic3r { // Returns the estimated time, in seconds float get_time() const; - // Returns the estimated time, in format HHh MMm SSs - std::string get_time_hms() const; + // Returns the estimated time, in format DDd HHh MMm SSs + std::string get_time_dhms() const; private: void _reset(); + void _reset_time(); void _reset_blocks(); + void _set_default_as_default(); + void _set_default_as_silent(); + + void _set_blocks_st_synchronize(bool state); + // Calculates the time estimate void _calculate_time(); @@ -353,6 +378,9 @@ namespace Slic3r { void _recalculate_trapezoids(); + // Returns the given time is seconds in format DDd HHh MMm SSs + static std::string _get_time_dhms(float time_in_secs); + #if ENABLE_MOVE_STATS void _log_moves_stats() const; #endif // ENABLE_MOVE_STATS diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index c56e64c6c4..c5b0edbdd0 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -233,7 +233,8 @@ public: PrintRegionPtrs regions; PlaceholderParser placeholder_parser; // TODO: status_cb - std::string estimated_print_time; + std::string estimated_default_print_time; + std::string estimated_silent_print_time; double total_used_filament, total_extruded_volume, total_cost, total_weight; std::map filament_stats; PrintState state; diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index ef9c5345f4..7ccbe01114 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -152,8 +152,10 @@ _constant() %code%{ RETVAL = &THIS->skirt; %}; Ref brim() %code%{ RETVAL = &THIS->brim; %}; - std::string estimated_print_time() - %code%{ RETVAL = THIS->estimated_print_time; %}; + std::string estimated_default_print_time() + %code%{ RETVAL = THIS->estimated_default_print_time; %}; + std::string estimated_silent_print_time() + %code%{ RETVAL = THIS->estimated_silent_print_time; %}; PrintObjectPtrs* objects() %code%{ RETVAL = &THIS->objects; %}; From 4009fdcc1850ce8db5090f401db40a079fe81946 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 6 Jun 2018 11:00:36 +0200 Subject: [PATCH 02/26] Finalized format for gcode line containing remaining printing time --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 49 ++++++++++--------------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 6 +++ 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 553ddba083..ad82c6820f 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -37,15 +37,7 @@ static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; static const std::string ELAPSED_TIME_TAG_DEFAULT = ";_ELAPSED_TIME_DEFAULT: "; static const std::string ELAPSED_TIME_TAG_SILENT = ";_ELAPSED_TIME_SILENT: "; -#define REMAINING_TIME_USE_SINGLE_GCODE_COMMAND 1 -#if REMAINING_TIME_USE_SINGLE_GCODE_COMMAND -static const std::string REMAINING_TIME_CMD = "M998"; -#else -static const std::string REMAINING_TIME_CMD_DEFAULT = "M998"; -static const std::string REMAINING_TIME_CMD_SILENT = "M999"; -#endif // REMAINING_TIME_USE_SINGLE_GCODE_COMMAND - -static const std::string REMAINING_TIME_COMMENT = " ; estimated remaining time"; +static const std::string REMAINING_TIME_CMD = "M73"; #if ENABLE_MOVE_STATS static const std::string MOVE_TYPE_STR[Slic3r::GCodeTimeEstimator::Block::Num_Types] = @@ -307,12 +299,14 @@ namespace Slic3r { throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n")); } -#if REMAINING_TIME_USE_SINGLE_GCODE_COMMAND // this function expects elapsed time for default and silent mode to be into two consecutive lines inside the gcode if (boost::contains(line, ELAPSED_TIME_TAG_DEFAULT)) { std::string default_elapsed_time_str = line.substr(ELAPSED_TIME_TAG_DEFAULT.length()); - line = REMAINING_TIME_CMD + " D:" + _get_time_dhms(default_time - (float)atof(default_elapsed_time_str.c_str())); + float elapsed_time = (float)atof(default_elapsed_time_str.c_str()); + float remaining_time = default_time - elapsed_time; + line = REMAINING_TIME_CMD + " P" + std::to_string((int)(100.0f * elapsed_time / default_time)); + line += " R" + _get_time_minutes(remaining_time); std::string next_line; std::getline(in, next_line); @@ -325,7 +319,10 @@ namespace Slic3r { if (boost::contains(next_line, ELAPSED_TIME_TAG_SILENT)) { std::string silent_elapsed_time_str = next_line.substr(ELAPSED_TIME_TAG_SILENT.length()); - line += " S:" + _get_time_dhms(silent_time - (float)atof(silent_elapsed_time_str.c_str())) + REMAINING_TIME_COMMENT; + float elapsed_time = (float)atof(silent_elapsed_time_str.c_str()); + float remaining_time = silent_time - elapsed_time; + line += " Q" + std::to_string((int)(100.0f * elapsed_time / silent_time)); + line += " S" + _get_time_minutes(remaining_time); } else // found horphaned default elapsed time, skip the remaining time line output @@ -334,24 +331,6 @@ namespace Slic3r { else if (boost::contains(line, ELAPSED_TIME_TAG_SILENT)) // found horphaned silent elapsed time, skip the remaining time line output continue; -#else - bool processed = false; - if (boost::contains(line, ELAPSED_TIME_TAG_DEFAULT)) - { - std::string elapsed_time_str = line.substr(ELAPSED_TIME_TAG_DEFAULT.length()); - line = REMAINING_TIME_CMD_DEFAULT + " " + _get_time_dhms(default_time - (float)atof(elapsed_time_str.c_str())); - processed = true; - } - else if (boost::contains(line, ELAPSED_TIME_TAG_SILENT)) - { - std::string elapsed_time_str = line.substr(ELAPSED_TIME_TAG_SILENT.length()); - line = REMAINING_TIME_CMD_SILENT + " " + _get_time_dhms(silent_time - (float)atof(elapsed_time_str.c_str())); - processed = true; - } - - if (processed) - line += REMAINING_TIME_COMMENT; -#endif // REMAINING_TIME_USE_SINGLE_GCODE_COMMAND line += "\n"; fwrite((const void*)line.c_str(), 1, line.length(), out); @@ -573,6 +552,11 @@ namespace Slic3r { return _get_time_dhms(get_time()); } + std::string GCodeTimeEstimator::get_time_minutes() const + { + return _get_time_minutes(get_time()); + } + void GCodeTimeEstimator::_reset() { _curr.reset(); @@ -1339,6 +1323,11 @@ namespace Slic3r { return buffer; } + std::string GCodeTimeEstimator::_get_time_minutes(float time_in_secs) + { + return std::to_string((int)(::roundf(time_in_secs / 60.0f))); + } + #if ENABLE_MOVE_STATS void GCodeTimeEstimator::_log_moves_stats() const { diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index c3fe0f04c9..14ff1efeac 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -297,6 +297,9 @@ namespace Slic3r { // Returns the estimated time, in format DDd HHh MMm SSs std::string get_time_dhms() const; + // Returns the estimated time, in minutes (integer) + std::string get_time_minutes() const; + private: void _reset(); void _reset_time(); @@ -381,6 +384,9 @@ namespace Slic3r { // Returns the given time is seconds in format DDd HHh MMm SSs static std::string _get_time_dhms(float time_in_secs); + // Returns the given, in minutes (integer) + static std::string _get_time_minutes(float time_in_secs); + #if ENABLE_MOVE_STATS void _log_moves_stats() const; #endif // ENABLE_MOVE_STATS From 71d750c1b86f1759a44e9bb4525fff41a259f13a Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 6 Jun 2018 12:21:24 +0200 Subject: [PATCH 03/26] Remaining time gcode line exported only for Marlin firmware --- xs/src/libslic3r/GCode.cpp | 42 ++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 28c15e2fd7..c3af90232f 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -375,7 +375,8 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ } fclose(file); - GCodeTimeEstimator::post_process_elapsed_times(path_tmp, m_default_time_estimator.get_time(), m_silent_time_estimator.get_time()); + if (m_default_time_estimator.get_dialect() == gcfMarlin) + GCodeTimeEstimator::post_process_elapsed_times(path_tmp, m_default_time_estimator.get_time(), m_silent_time_estimator.get_time()); if (! this->m_placeholder_parser_failed_templates.empty()) { // G-code export proceeded, but some of the PlaceholderParser substitutions failed. @@ -409,8 +410,11 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) // resets time estimators m_default_time_estimator.reset(); m_default_time_estimator.set_dialect(print.config.gcode_flavor); - m_silent_time_estimator.reset(); - m_silent_time_estimator.set_dialect(print.config.gcode_flavor); + if (print.config.gcode_flavor == gcfMarlin) + { + m_silent_time_estimator.reset(); + m_silent_time_estimator.set_dialect(print.config.gcode_flavor); + } // resets analyzer m_analyzer.reset(); @@ -602,8 +606,11 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) } // before start gcode time estimation - _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); - _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); + if (m_default_time_estimator.get_dialect() == gcfMarlin) + { + _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); + _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); + } // Write the custom start G-code _writeln(file, start_gcode); @@ -810,8 +817,11 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()), &config)); } // before end gcode time estimation - _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); - _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); + if (m_default_time_estimator.get_dialect() == gcfMarlin) + { + _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); + _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); + } _writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id(), &config)); } _write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% @@ -819,7 +829,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) // calculates estimated printing time m_default_time_estimator.calculate_time(); - m_silent_time_estimator.calculate_time(); + if (m_default_time_estimator.get_dialect() == gcfMarlin) + m_silent_time_estimator.calculate_time(); // Get filament stats. print.filament_stats.clear(); @@ -828,7 +839,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) print.total_weight = 0.; print.total_cost = 0.; print.estimated_default_print_time = m_default_time_estimator.get_time_dhms(); - print.estimated_silent_print_time = m_silent_time_estimator.get_time_dhms(); + print.estimated_silent_print_time = (m_default_time_estimator.get_dialect() == gcfMarlin) ? m_silent_time_estimator.get_time_dhms() : "N/A"; for (const Extruder &extruder : m_writer.extruders()) { double used_filament = extruder.used_filament(); double extruded_volume = extruder.extruded_volume(); @@ -849,7 +860,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) } _write_format(file, "; total filament cost = %.1lf\n", print.total_cost); _write_format(file, "; estimated printing time (default mode) = %s\n", m_default_time_estimator.get_time_dhms().c_str()); - _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); + if (m_default_time_estimator.get_dialect() == gcfMarlin) + _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); // Append full config. _write(file, "\n"); @@ -1418,8 +1430,11 @@ void GCode::process_layer( _write(file, gcode); // after layer time estimation - _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); - _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); + if (m_default_time_estimator.get_dialect() == gcfMarlin) + { + _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); + _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); + } } void GCode::apply_print_config(const PrintConfig &print_config) @@ -2079,7 +2094,8 @@ void GCode::_write(FILE* file, const char *what) fwrite(gcode, 1, ::strlen(gcode), file); // updates time estimator and gcode lines vector m_default_time_estimator.add_gcode_block(gcode); - m_silent_time_estimator.add_gcode_block(gcode); + if (m_default_time_estimator.get_dialect() == gcfMarlin) + m_silent_time_estimator.add_gcode_block(gcode); } } From fd4feb689ea1b21380c492264d305bc91b4cc5b2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 20 Jun 2018 14:20:48 +0200 Subject: [PATCH 04/26] Added prototype for "Kinematics" Page + Added enum_labels to localizations + Added bold font for the name of Options Groups --- xs/src/libslic3r/PrintConfig.cpp | 61 +++++++++++++++------------- xs/src/slic3r/GUI/GUI.cpp | 22 ++++++++++ xs/src/slic3r/GUI/GUI.hpp | 5 ++- xs/src/slic3r/GUI/OptionsGroup.hpp | 4 +- xs/src/slic3r/GUI/Preset.cpp | 3 +- xs/src/slic3r/GUI/Tab.cpp | 64 +++++++++++++++++++++++++++++- xs/src/slic3r/GUI/Tab.hpp | 1 + 7 files changed, 129 insertions(+), 31 deletions(-) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index b77a3a76eb..6a859096f3 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -283,11 +283,11 @@ PrintConfigDef::PrintConfigDef() def->enum_values.push_back("hilbertcurve"); def->enum_values.push_back("archimedeanchords"); def->enum_values.push_back("octagramspiral"); - def->enum_labels.push_back("Rectilinear"); - def->enum_labels.push_back("Concentric"); - def->enum_labels.push_back("Hilbert Curve"); - def->enum_labels.push_back("Archimedean Chords"); - def->enum_labels.push_back("Octagram Spiral"); + def->enum_labels.push_back(L("Rectilinear")); + def->enum_labels.push_back(L("Concentric")); + def->enum_labels.push_back(L("Hilbert Curve")); + def->enum_labels.push_back(L("Archimedean Chords")); + def->enum_labels.push_back(L("Octagram Spiral")); // solid_fill_pattern is an obsolete equivalent to external_fill_pattern. def->aliases.push_back("solid_fill_pattern"); def->default_value = new ConfigOptionEnum(ipRectilinear); @@ -617,19 +617,19 @@ PrintConfigDef::PrintConfigDef() def->enum_values.push_back("hilbertcurve"); def->enum_values.push_back("archimedeanchords"); def->enum_values.push_back("octagramspiral"); - def->enum_labels.push_back("Rectilinear"); - def->enum_labels.push_back("Grid"); - def->enum_labels.push_back("Triangles"); - def->enum_labels.push_back("Stars"); - def->enum_labels.push_back("Cubic"); - def->enum_labels.push_back("Line"); - def->enum_labels.push_back("Concentric"); - def->enum_labels.push_back("Honeycomb"); - def->enum_labels.push_back("3D Honeycomb"); - def->enum_labels.push_back("Gyroid"); - def->enum_labels.push_back("Hilbert Curve"); - def->enum_labels.push_back("Archimedean Chords"); - def->enum_labels.push_back("Octagram Spiral"); + def->enum_labels.push_back(L("Rectilinear")); + def->enum_labels.push_back(L("Grid")); + def->enum_labels.push_back(L("Triangles")); + def->enum_labels.push_back(L("Stars")); + def->enum_labels.push_back(L("Cubic")); + def->enum_labels.push_back(L("Line")); + def->enum_labels.push_back(L("Concentric")); + def->enum_labels.push_back(L("Honeycomb")); + def->enum_labels.push_back(L("3D Honeycomb")); + def->enum_labels.push_back(L("Gyroid")); + def->enum_labels.push_back(L("Hilbert Curve")); + def->enum_labels.push_back(L("Archimedean Chords")); + def->enum_labels.push_back(L("Octagram Spiral")); def->default_value = new ConfigOptionEnum(ipStars); def = this->add("first_layer_acceleration", coFloat); @@ -737,7 +737,7 @@ PrintConfigDef::PrintConfigDef() def->enum_labels.push_back("Mach3/LinuxCNC"); def->enum_labels.push_back("Machinekit"); def->enum_labels.push_back("Smoothie"); - def->enum_labels.push_back("No extrusion"); + def->enum_labels.push_back(L("No extrusion")); def->default_value = new ConfigOptionEnum(gcfMarlin); def = this->add("infill_acceleration", coFloat); @@ -1265,10 +1265,10 @@ PrintConfigDef::PrintConfigDef() def->enum_values.push_back("nearest"); def->enum_values.push_back("aligned"); def->enum_values.push_back("rear"); - def->enum_labels.push_back("Random"); - def->enum_labels.push_back("Nearest"); - def->enum_labels.push_back("Aligned"); - def->enum_labels.push_back("Rear"); + def->enum_labels.push_back(L("Random")); + def->enum_labels.push_back(L("Nearest")); + def->enum_labels.push_back(L("Aligned")); + def->enum_labels.push_back(L("Rear")); def->default_value = new ConfigOptionEnum(spAligned); #if 0 @@ -1481,7 +1481,14 @@ PrintConfigDef::PrintConfigDef() def->label = L("Single Extruder Multi Material"); def->tooltip = L("The printer multiplexes filaments into a single hot end."); def->cli = "single-extruder-multi-material!"; - def->default_value = new ConfigOptionBool(false); + def->default_value = new ConfigOptionBool(false); + + // -- ! Kinematics options + def = this->add("silent_mode", coBool); + def->label = L("Silent mode"); + def->tooltip = L("Set silent mode for the G-code flavor"); + def->default_value = new ConfigOptionBool(true); + // -- ! def = this->add("support_material", coBool); def->label = L("Generate support material"); @@ -1621,9 +1628,9 @@ PrintConfigDef::PrintConfigDef() def->enum_values.push_back("rectilinear"); def->enum_values.push_back("rectilinear-grid"); def->enum_values.push_back("honeycomb"); - def->enum_labels.push_back("rectilinear"); - def->enum_labels.push_back("rectilinear grid"); - def->enum_labels.push_back("honeycomb"); + def->enum_labels.push_back(L("Rectilinear")); + def->enum_labels.push_back(L("Rectilinear grid")); + def->enum_labels.push_back(L("Honeycomb")); def->default_value = new ConfigOptionEnum(smpRectilinear); def = this->add("support_material_spacing", coFloat); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index e2f3925fcb..1751f4548a 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -117,6 +117,9 @@ std::vector g_tabs_list; wxLocale* g_wxLocale; +wxFont g_small_font; +wxFont g_bold_font; + std::shared_ptr m_optgroup; double m_brim_width = 0.0; wxButton* g_wiping_dialog_button = nullptr; @@ -149,10 +152,21 @@ void update_label_colours_from_appconfig() } } +static void init_fonts() +{ + g_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + g_bold_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); +#ifdef __WXMAC__ + g_small_font.SetPointSize(11); + g_bold_font.SetPointSize(13); +#endif /*__WXMAC__*/ +} + void set_wxapp(wxApp *app) { g_wxApp = app; init_label_colours(); + init_fonts(); } void set_main_frame(wxFrame *main_frame) @@ -668,6 +682,14 @@ void set_label_clr_sys(const wxColour& clr) { g_AppConfig->save(); } +const wxFont& small_font(){ + return g_small_font; +} + +const wxFont& bold_font(){ + return g_bold_font; +} + const wxColour& get_label_clr_default() { return g_color_label_default; } diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 2853544462..663815f68f 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -11,7 +11,7 @@ class wxApp; class wxWindow; class wxFrame; -class wxWindow; +class wxFont; class wxMenuBar; class wxNotebook; class wxComboCtrl; @@ -99,6 +99,9 @@ unsigned get_colour_approx_luma(const wxColour &colour); void set_label_clr_modified(const wxColour& clr); void set_label_clr_sys(const wxColour& clr); +const wxFont& small_font(); +const wxFont& bold_font(); + extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); // This is called when closing the application, when loading a config file or when starting the config wizard diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 83b5b1233f..f351476423 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -129,7 +129,9 @@ public: OptionsGroup(wxWindow* _parent, const wxString& title, bool is_tab_opt=false) : m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), staticbox(title!="") { - sizer = (staticbox ? new wxStaticBoxSizer(new wxStaticBox(_parent, wxID_ANY, title), wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); + auto stb = new wxStaticBox(_parent, wxID_ANY, title); + stb->SetFont(bold_font()); + sizer = (staticbox ? new wxStaticBoxSizer(stb/*new wxStaticBox(_parent, wxID_ANY, title)*/, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); auto num_columns = 1U; if (label_width != 0) num_columns++; if (extra_column != nullptr) num_columns++; diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index 68982185b4..fa29b0fb58 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -325,7 +325,8 @@ const std::vector& Preset::printer_options() "octoprint_host", "octoprint_apikey", "octoprint_cafile", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height", "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode", "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction", - "cooling_tube_length", "parking_pos_retraction", "max_print_height", "default_print_profile", "inherits", + "cooling_tube_length", "parking_pos_retraction", "max_print_height", "default_print_profile", "inherits", + "silent_mode" }; s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end()); } diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 6eabc2f474..574de9afb9 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1627,6 +1627,16 @@ void TabPrinter::build() optgroup = page->new_optgroup(_(L("Firmware"))); optgroup->append_single_option_line("gcode_flavor"); + optgroup->append_single_option_line("silent_mode"); + + optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value){ + wxTheApp->CallAfter([this, opt_key, value](){ + if (opt_key.compare("gcode_flavor") == 0) + build_extruder_pages(); + update_dirty(); + on_value_change(opt_key, value); + }); + }; optgroup = page->new_optgroup(_(L("Advanced"))); optgroup->append_single_option_line("use_relative_e_distances"); @@ -1708,8 +1718,57 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){ on_value_change("extruders_count", extruders_count); } -void TabPrinter::build_extruder_pages(){ +PageShp TabPrinter::create_kinematics_page() +{ + auto page = add_options_page(_(L("Kinematics")), "cog.png", true); + auto optgroup = page->new_optgroup(_(L("Maximum accelerations"))); +// optgroup->append_single_option_line("max_acceleration_x"); +// optgroup->append_single_option_line("max_acceleration_y"); +// optgroup->append_single_option_line("max_acceleration_z"); + + optgroup = page->new_optgroup(_(L("Maximum feedrates"))); +// optgroup->append_single_option_line("max_feedrate_x"); +// optgroup->append_single_option_line("max_feedrate_y"); +// optgroup->append_single_option_line("max_feedrate_z"); + + optgroup = page->new_optgroup(_(L("Starting Acceleration"))); +// optgroup->append_single_option_line("start_acceleration"); +// optgroup->append_single_option_line("start_retract_acceleration"); + + optgroup = page->new_optgroup(_(L("Advanced"))); +// optgroup->append_single_option_line("min_feedrate_for_print_moves"); +// optgroup->append_single_option_line("min_feedrate_for_travel_moves"); +// optgroup->append_single_option_line("max_jerk_x"); +// optgroup->append_single_option_line("max_jerk_y"); +// optgroup->append_single_option_line("max_jerk_z"); + + return page; +} + + +void TabPrinter::build_extruder_pages() +{ size_t n_before_extruders = 2; // Count of pages before Extruder pages + bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; + + // Add/delete Kinematics page according to is_marlin_flavor + size_t existed_page = 0; + for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already + if (m_pages[i]->title().find(_(L("Kinematics"))) != std::string::npos) { + if (!is_marlin_flavor) + m_pages.erase(m_pages.begin() + i); + else + existed_page = i; + break; + } + + if (existed_page < n_before_extruders && is_marlin_flavor){ + auto page = create_kinematics_page(); + m_pages.insert(m_pages.begin() + n_before_extruders, page); + } + + if (is_marlin_flavor) + n_before_extruders++; size_t n_after_single_extruder_MM = 2; // Count of pages after single_extruder_multi_material page if (m_extruders_count_old == m_extruders_count || @@ -1818,6 +1877,9 @@ void TabPrinter::update(){ get_field("toolchange_gcode")->toggle(have_multiple_extruders); get_field("single_extruder_multi_material")->toggle(have_multiple_extruders); + bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; + get_field("silent_mode")->toggle(is_marlin_flavor); + for (size_t i = 0; i < m_extruders_count; ++i) { bool have_retract_length = m_config->opt_float("retract_length", i) > 0; diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp index d6bf2cf43e..ab63bcc783 100644 --- a/xs/src/slic3r/GUI/Tab.hpp +++ b/xs/src/slic3r/GUI/Tab.hpp @@ -330,6 +330,7 @@ public: void update() override; void update_serial_ports(); void extruders_count_changed(size_t extruders_count); + PageShp create_kinematics_page(); void build_extruder_pages(); void on_preset_loaded() override; void init_options_list() override; From b6ebbdb94a1201479f08f2ab901d4cd74c48119e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 20 Jun 2018 16:30:55 +0200 Subject: [PATCH 05/26] Updated "Machine limits"(Kinematics) page according to the new config --- xs/src/libslic3r/PrintConfig.cpp | 8 ++-- xs/src/slic3r/GUI/Preset.cpp | 6 ++- xs/src/slic3r/GUI/Tab.cpp | 74 +++++++++++++++++++++++++------- 3 files changed, 68 insertions(+), 20 deletions(-) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 9e384898cb..54aa3b424b 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -906,7 +906,7 @@ PrintConfigDef::PrintConfigDef() def->tooltip = L("Minimum feedrate when extruding") + " (M205 S)"; def->sidetext = L("mm/s"); def->min = 0; - def->default_value = new ConfigOptionFloats(0., 0.); + def->default_value = new ConfigOptionFloats{ 0., 0. }; // M205 T... [mm/sec] def = this->add("machine_min_travel_rate", coFloats); @@ -915,7 +915,7 @@ PrintConfigDef::PrintConfigDef() def->tooltip = L("Minimum travel feedrate") + " (M205 T)"; def->sidetext = L("mm/s"); def->min = 0; - def->default_value = new ConfigOptionFloats(0., 0.); + def->default_value = new ConfigOptionFloats{ 0., 0. }; // M204 S... [mm/sec^2] def = this->add("machine_max_acceleration_extruding", coFloats); @@ -1620,8 +1620,8 @@ PrintConfigDef::PrintConfigDef() def->min = 0; def->enum_values.push_back("0"); def->enum_values.push_back("0.2"); - def->enum_labels.push_back("0 (soluble)"); - def->enum_labels.push_back("0.2 (detachable)"); + def->enum_labels.push_back((boost::format("0 (%1%)") % L("soluble")).str()); + def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("detachable")).str()); def->default_value = new ConfigOptionFloat(0.2); def = this->add("support_material_enforce_layers", coInt); diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index fa29b0fb58..98c5914e2a 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -326,7 +326,11 @@ const std::vector& Preset::printer_options() "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode", "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction", "cooling_tube_length", "parking_pos_retraction", "max_print_height", "default_print_profile", "inherits", - "silent_mode" + "silent_mode","machine_max_acceleration_extruding", "machine_max_acceleration_retracting", + "machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e", + "machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e", + "machine_min_extruding_rate", "machine_min_travel_rate", + "machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e" }; s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end()); } diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 574de9afb9..33636c7098 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1720,27 +1720,71 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){ PageShp TabPrinter::create_kinematics_page() { - auto page = add_options_page(_(L("Kinematics")), "cog.png", true); + auto page = add_options_page(_(L("Machine limits")), "cog.png", true); auto optgroup = page->new_optgroup(_(L("Maximum accelerations"))); -// optgroup->append_single_option_line("max_acceleration_x"); -// optgroup->append_single_option_line("max_acceleration_y"); -// optgroup->append_single_option_line("max_acceleration_z"); + auto line = Line{ _(L("Standard/Silent mode")), "" }; + line.append_option(optgroup->get_option("machine_max_acceleration_x", 0)); + line.append_option(optgroup->get_option("machine_max_acceleration_x", 1)); + optgroup->append_line(line); + line = Line{ "", "" }; + line.append_option(optgroup->get_option("machine_max_acceleration_y", 0)); + line.append_option(optgroup->get_option("machine_max_acceleration_y", 1)); + optgroup->append_line(line); + line = Line{ _(L("Standard/Silent mode")), "" }; + line.append_option(optgroup->get_option("machine_max_acceleration_z", 0)); + line.append_option(optgroup->get_option("machine_max_acceleration_z", 1)); + optgroup->append_line(line); + line = Line{ _(L("Standard/Silent mode")), "" }; + line.append_option(optgroup->get_option("machine_max_acceleration_e", 0)); + line.append_option(optgroup->get_option("machine_max_acceleration_e", 1)); + optgroup->append_line(line); +// optgroup->append_single_option_line("machine_max_acceleration_x", 0); +// optgroup->append_single_option_line("machine_max_acceleration_y", 0); +// optgroup->append_single_option_line("machine_max_acceleration_z", 0); +// optgroup->append_single_option_line("machine_max_acceleration_e", 0); optgroup = page->new_optgroup(_(L("Maximum feedrates"))); -// optgroup->append_single_option_line("max_feedrate_x"); -// optgroup->append_single_option_line("max_feedrate_y"); -// optgroup->append_single_option_line("max_feedrate_z"); + optgroup->append_single_option_line("machine_max_feedrate_x", 0); + optgroup->append_single_option_line("machine_max_feedrate_y", 0); + optgroup->append_single_option_line("machine_max_feedrate_z", 0); + optgroup->append_single_option_line("machine_max_feedrate_e", 0); optgroup = page->new_optgroup(_(L("Starting Acceleration"))); -// optgroup->append_single_option_line("start_acceleration"); -// optgroup->append_single_option_line("start_retract_acceleration"); + optgroup->append_single_option_line("machine_max_acceleration_extruding", 0); + optgroup->append_single_option_line("machine_max_acceleration_retracting", 0); optgroup = page->new_optgroup(_(L("Advanced"))); -// optgroup->append_single_option_line("min_feedrate_for_print_moves"); -// optgroup->append_single_option_line("min_feedrate_for_travel_moves"); -// optgroup->append_single_option_line("max_jerk_x"); -// optgroup->append_single_option_line("max_jerk_y"); -// optgroup->append_single_option_line("max_jerk_z"); + optgroup->append_single_option_line("machine_min_extruding_rate", 0); + optgroup->append_single_option_line("machine_min_travel_rate", 0); + optgroup->append_single_option_line("machine_max_jerk_x", 0); + optgroup->append_single_option_line("machine_max_jerk_y", 0); + optgroup->append_single_option_line("machine_max_jerk_z", 0); + optgroup->append_single_option_line("machine_max_jerk_e", 0); + + //for silent mode +// optgroup = page->new_optgroup(_(L("Maximum accelerations"))); +// optgroup->append_single_option_line("machine_max_acceleration_x", 1); +// optgroup->append_single_option_line("machine_max_acceleration_y", 1); +// optgroup->append_single_option_line("machine_max_acceleration_z", 1); +// optgroup->append_single_option_line("machine_max_acceleration_e", 1); + + optgroup = page->new_optgroup(_(L("Maximum feedrates (Silent mode)"))); + optgroup->append_single_option_line("machine_max_feedrate_x", 1); + optgroup->append_single_option_line("machine_max_feedrate_y", 1); + optgroup->append_single_option_line("machine_max_feedrate_z", 1); + optgroup->append_single_option_line("machine_max_feedrate_e", 1); + + optgroup = page->new_optgroup(_(L("Starting Acceleration (Silent mode)"))); + optgroup->append_single_option_line("machine_max_acceleration_extruding", 1); + optgroup->append_single_option_line("machine_max_acceleration_retracting", 1); + + optgroup = page->new_optgroup(_(L("Advanced (Silent mode)"))); + optgroup->append_single_option_line("machine_min_extruding_rate", 1); + optgroup->append_single_option_line("machine_min_travel_rate", 1); + optgroup->append_single_option_line("machine_max_jerk_x", 1); + optgroup->append_single_option_line("machine_max_jerk_y", 1); + optgroup->append_single_option_line("machine_max_jerk_z", 1); + optgroup->append_single_option_line("machine_max_jerk_e", 1); return page; } @@ -1754,7 +1798,7 @@ void TabPrinter::build_extruder_pages() // Add/delete Kinematics page according to is_marlin_flavor size_t existed_page = 0; for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already - if (m_pages[i]->title().find(_(L("Kinematics"))) != std::string::npos) { + if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) { if (!is_marlin_flavor) m_pages.erase(m_pages.begin() + i); else From 4454c3437f2e031ea54af77ed40cc445ca00d596 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 21 Jun 2018 16:15:56 +0200 Subject: [PATCH 06/26] "Machine limits" page is completed --- xs/src/libslic3r/PrintConfig.cpp | 34 ++++++---- xs/src/slic3r/GUI/Field.cpp | 16 +++++ xs/src/slic3r/GUI/Field.hpp | 28 ++++++++ xs/src/slic3r/GUI/OptionsGroup.cpp | 4 +- xs/src/slic3r/GUI/OptionsGroup.hpp | 8 ++- xs/src/slic3r/GUI/Tab.cpp | 104 +++++++++++++---------------- 6 files changed, 120 insertions(+), 74 deletions(-) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 54aa3b424b..68fc2da244 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -856,6 +856,12 @@ PrintConfigDef::PrintConfigDef() def->min = 0; def->default_value = new ConfigOptionFloat(0.3); + def = this->add("silent_mode", coBool); + def->label = L("Support silent mode"); + def->tooltip = L("Set silent mode for the G-code flavor"); + def->default_value = new ConfigOptionBool(true); + + const int machine_linits_opt_width = 70; { struct AxisDefault { std::string name; @@ -874,65 +880,72 @@ PrintConfigDef::PrintConfigDef() std::string axis_upper = boost::to_upper_copy(axis.name); // Add the machine feedrate limits for XYZE axes. (M203) def = this->add("machine_max_feedrate_" + axis.name, coFloats); - def->label = (boost::format(L("Maximum feedrate %1%")) % axis_upper).str(); + def->full_label = (boost::format(L("Maximum feedrate %1%")) % axis_upper).str(); def->category = L("Machine limits"); def->tooltip = (boost::format(L("Maximum feedrate of the %1% axis")) % axis_upper).str(); def->sidetext = L("mm/s"); def->min = 0; + def->width = machine_linits_opt_width; def->default_value = new ConfigOptionFloats(axis.max_feedrate); // Add the machine acceleration limits for XYZE axes (M201) def = this->add("machine_max_acceleration_" + axis.name, coFloats); - def->label = (boost::format(L("Maximum acceleration %1%")) % axis_upper).str(); + def->full_label = (boost::format(L("Maximum acceleration %1%")) % axis_upper).str(); def->category = L("Machine limits"); def->tooltip = (boost::format(L("Maximum acceleration of the %1% axis")) % axis_upper).str(); def->sidetext = L("mm/s²"); def->min = 0; + def->width = machine_linits_opt_width; def->default_value = new ConfigOptionFloats(axis.max_acceleration); // Add the machine jerk limits for XYZE axes (M205) def = this->add("machine_max_jerk_" + axis.name, coFloats); - def->label = (boost::format(L("Maximum jerk %1%")) % axis_upper).str(); + def->full_label = (boost::format(L("Maximum jerk %1%")) % axis_upper).str(); def->category = L("Machine limits"); def->tooltip = (boost::format(L("Maximum jerk of the %1% axis")) % axis_upper).str(); def->sidetext = L("mm/s"); def->min = 0; + def->width = machine_linits_opt_width; def->default_value = new ConfigOptionFloats(axis.max_jerk); } } // M205 S... [mm/sec] def = this->add("machine_min_extruding_rate", coFloats); - def->label = L("Minimum feedrate when extruding"); + def->full_label = L("Minimum feedrate when extruding"); def->category = L("Machine limits"); def->tooltip = L("Minimum feedrate when extruding") + " (M205 S)"; def->sidetext = L("mm/s"); def->min = 0; + def->width = machine_linits_opt_width; def->default_value = new ConfigOptionFloats{ 0., 0. }; // M205 T... [mm/sec] def = this->add("machine_min_travel_rate", coFloats); - def->label = L("Minimum travel feedrate"); + def->full_label = L("Minimum travel feedrate"); def->category = L("Machine limits"); def->tooltip = L("Minimum travel feedrate") + " (M205 T)"; def->sidetext = L("mm/s"); def->min = 0; + def->width = machine_linits_opt_width; def->default_value = new ConfigOptionFloats{ 0., 0. }; // M204 S... [mm/sec^2] def = this->add("machine_max_acceleration_extruding", coFloats); - def->label = L("Maximum acceleration when extruding"); + def->full_label = L("Maximum acceleration when extruding"); def->category = L("Machine limits"); def->tooltip = L("Maximum acceleration when extruding") + " (M204 S)"; def->sidetext = L("mm/s²"); def->min = 0; + def->width = machine_linits_opt_width; def->default_value = new ConfigOptionFloats(1250., 1250.); // M204 T... [mm/sec^2] def = this->add("machine_max_acceleration_retracting", coFloats); - def->label = L("Maximum acceleration when retracting"); + def->full_label = L("Maximum acceleration when retracting"); def->category = L("Machine limits"); def->tooltip = L("Maximum acceleration when retracting") + " (M204 T)"; def->sidetext = L("mm/s²"); def->min = 0; + def->width = machine_linits_opt_width; def->default_value = new ConfigOptionFloats(1250., 1250.); def = this->add("max_fan_speed", coInts); @@ -1565,13 +1578,6 @@ PrintConfigDef::PrintConfigDef() def->cli = "single-extruder-multi-material!"; def->default_value = new ConfigOptionBool(false); - // -- ! Kinematics options - def = this->add("silent_mode", coBool); - def->label = L("Silent mode"); - def->tooltip = L("Set silent mode for the G-code flavor"); - def->default_value = new ConfigOptionBool(true); - // -- ! - def = this->add("support_material", coBool); def->label = L("Generate support material"); def->category = L("Support material"); diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp index 43c9e7db9e..46b04d959b 100644 --- a/xs/src/slic3r/GUI/Field.cpp +++ b/xs/src/slic3r/GUI/Field.cpp @@ -665,6 +665,22 @@ boost::any& PointCtrl::get_value() return m_value = ret_point; } +void StaticText::BUILD() +{ + auto size = wxSize(wxDefaultSize); + if (m_opt.height >= 0) size.SetHeight(m_opt.height); + if (m_opt.width >= 0) size.SetWidth(m_opt.width); + + wxString legend(static_cast(m_opt.default_value)->value); + auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size); + temp->SetFont(bold_font()); + + // // recast as a wxWindow to fit the calling convention + window = dynamic_cast(temp); + + temp->SetToolTip(get_tooltip_text(legend)); +} + } // GUI } // Slic3r diff --git a/xs/src/slic3r/GUI/Field.hpp b/xs/src/slic3r/GUI/Field.hpp index 948178d3ee..fb6116b79c 100644 --- a/xs/src/slic3r/GUI/Field.hpp +++ b/xs/src/slic3r/GUI/Field.hpp @@ -384,6 +384,34 @@ public: wxSizer* getSizer() override { return sizer; } }; +class StaticText : public Field { + using Field::Field; +public: + StaticText(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {} + StaticText(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {} + ~StaticText() {} + + wxWindow* window{ nullptr }; + void BUILD() override; + + void set_value(const std::string& value, bool change_event = false) { + m_disable_change_event = !change_event; + dynamic_cast(window)->SetLabel(value); + m_disable_change_event = false; + } + void set_value(const boost::any& value, bool change_event = false) { + m_disable_change_event = !change_event; + dynamic_cast(window)->SetLabel(boost::any_cast(value)); + m_disable_change_event = false; + } + + boost::any& get_value()override { return m_value; } + + void enable() override { dynamic_cast(window)->Enable(); }; + void disable() override{ dynamic_cast(window)->Disable(); }; + wxWindow* getWindow() override { return window; } +}; + } // GUI } // Slic3r diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 57659d03dd..053293ee60 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -31,6 +31,8 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co m_fields.emplace(id, STDMOVE(Choice::Create(parent(), opt, id))); } else if (opt.gui_type.compare("slider") == 0) { } else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl + } else if (opt.gui_type.compare("legend") == 0) { // StaticText + m_fields.emplace(id, STDMOVE(StaticText::Create(parent(), opt, id))); } else { switch (opt.type) { case coFloatOrPercent: @@ -86,7 +88,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co if (!this->m_disabled) this->back_to_sys_value(opt_id); }; - if (!m_is_tab_opt) { + if (!m_show_modified_btns) { field->m_Undo_btn->Hide(); field->m_Undo_to_sys_btn->Hide(); } diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index f351476423..422e1afd9e 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -127,8 +127,12 @@ public: inline void enable() { for (auto& field : m_fields) field.second->enable(); } inline void disable() { for (auto& field : m_fields) field.second->disable(); } + void set_show_modified_btns_val(bool show) { + m_show_modified_btns = show; + } + OptionsGroup(wxWindow* _parent, const wxString& title, bool is_tab_opt=false) : - m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), staticbox(title!="") { + m_parent(_parent), title(title), m_show_modified_btns(is_tab_opt), staticbox(title!="") { auto stb = new wxStaticBox(_parent, wxID_ANY, title); stb->SetFont(bold_font()); sizer = (staticbox ? new wxStaticBoxSizer(stb/*new wxStaticBox(_parent, wxID_ANY, title)*/, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); @@ -158,7 +162,7 @@ protected: bool m_disabled {false}; wxGridSizer* m_grid_sizer {nullptr}; // "true" if option is created in preset tabs - bool m_is_tab_opt{ false }; + bool m_show_modified_btns{ false }; // This panel is needed for correct showing of the ToolTips for Button, StaticText and CheckBox // Tooltips on GTK doesn't work inside wxStaticBoxSizer unless you insert a panel diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 33636c7098..583773c1e7 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1718,73 +1718,63 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){ on_value_change("extruders_count", extruders_count); } +void append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key) +{ + auto option = optgroup->get_option(opt_key, 0); + auto line = Line{ option.opt.full_label, "" }; + line.append_option(option); + line.append_option(optgroup->get_option(opt_key, 1)); + optgroup->append_line(line); +} + PageShp TabPrinter::create_kinematics_page() { auto page = add_options_page(_(L("Machine limits")), "cog.png", true); - auto optgroup = page->new_optgroup(_(L("Maximum accelerations"))); - auto line = Line{ _(L("Standard/Silent mode")), "" }; - line.append_option(optgroup->get_option("machine_max_acceleration_x", 0)); - line.append_option(optgroup->get_option("machine_max_acceleration_x", 1)); + + // Legend for OptionsGroups + auto optgroup = page->new_optgroup(_(L(""))); + optgroup->set_show_modified_btns_val(false); + optgroup->label_width = 230; + auto line = Line{ "", "" }; + + ConfigOptionDef def; + def.type = coString; + def.width = 150; + def.gui_type = "legend"; + def.tooltip = L("Values in this column are for Full Power mode"); + def.default_value = new ConfigOptionString{ L("Full Power")}; + + auto option = Option(def, "full_power_legend"); + line.append_option(option); + + def.tooltip = L("Values in this column are for Silent mode"); + def.default_value = new ConfigOptionString{ L("Silent") }; + option = Option(def, "silent_legend"); + line.append_option(option); + optgroup->append_line(line); - line = Line{ "", "" }; - line.append_option(optgroup->get_option("machine_max_acceleration_y", 0)); - line.append_option(optgroup->get_option("machine_max_acceleration_y", 1)); - optgroup->append_line(line); - line = Line{ _(L("Standard/Silent mode")), "" }; - line.append_option(optgroup->get_option("machine_max_acceleration_z", 0)); - line.append_option(optgroup->get_option("machine_max_acceleration_z", 1)); - optgroup->append_line(line); - line = Line{ _(L("Standard/Silent mode")), "" }; - line.append_option(optgroup->get_option("machine_max_acceleration_e", 0)); - line.append_option(optgroup->get_option("machine_max_acceleration_e", 1)); - optgroup->append_line(line); -// optgroup->append_single_option_line("machine_max_acceleration_x", 0); -// optgroup->append_single_option_line("machine_max_acceleration_y", 0); -// optgroup->append_single_option_line("machine_max_acceleration_z", 0); -// optgroup->append_single_option_line("machine_max_acceleration_e", 0); + + std::vector axes{ "x", "y", "z", "e" }; + optgroup = page->new_optgroup(_(L("Maximum accelerations"))); + for (const std::string &axis : axes) { + append_option_line(optgroup, "machine_max_acceleration_" + axis); + } optgroup = page->new_optgroup(_(L("Maximum feedrates"))); - optgroup->append_single_option_line("machine_max_feedrate_x", 0); - optgroup->append_single_option_line("machine_max_feedrate_y", 0); - optgroup->append_single_option_line("machine_max_feedrate_z", 0); - optgroup->append_single_option_line("machine_max_feedrate_e", 0); + for (const std::string &axis : axes) { + append_option_line(optgroup, "machine_max_feedrate_" + axis); + } optgroup = page->new_optgroup(_(L("Starting Acceleration"))); - optgroup->append_single_option_line("machine_max_acceleration_extruding", 0); - optgroup->append_single_option_line("machine_max_acceleration_retracting", 0); + append_option_line(optgroup, "machine_max_acceleration_extruding"); + append_option_line(optgroup, "machine_max_acceleration_retracting"); optgroup = page->new_optgroup(_(L("Advanced"))); - optgroup->append_single_option_line("machine_min_extruding_rate", 0); - optgroup->append_single_option_line("machine_min_travel_rate", 0); - optgroup->append_single_option_line("machine_max_jerk_x", 0); - optgroup->append_single_option_line("machine_max_jerk_y", 0); - optgroup->append_single_option_line("machine_max_jerk_z", 0); - optgroup->append_single_option_line("machine_max_jerk_e", 0); - - //for silent mode -// optgroup = page->new_optgroup(_(L("Maximum accelerations"))); -// optgroup->append_single_option_line("machine_max_acceleration_x", 1); -// optgroup->append_single_option_line("machine_max_acceleration_y", 1); -// optgroup->append_single_option_line("machine_max_acceleration_z", 1); -// optgroup->append_single_option_line("machine_max_acceleration_e", 1); - - optgroup = page->new_optgroup(_(L("Maximum feedrates (Silent mode)"))); - optgroup->append_single_option_line("machine_max_feedrate_x", 1); - optgroup->append_single_option_line("machine_max_feedrate_y", 1); - optgroup->append_single_option_line("machine_max_feedrate_z", 1); - optgroup->append_single_option_line("machine_max_feedrate_e", 1); - - optgroup = page->new_optgroup(_(L("Starting Acceleration (Silent mode)"))); - optgroup->append_single_option_line("machine_max_acceleration_extruding", 1); - optgroup->append_single_option_line("machine_max_acceleration_retracting", 1); - - optgroup = page->new_optgroup(_(L("Advanced (Silent mode)"))); - optgroup->append_single_option_line("machine_min_extruding_rate", 1); - optgroup->append_single_option_line("machine_min_travel_rate", 1); - optgroup->append_single_option_line("machine_max_jerk_x", 1); - optgroup->append_single_option_line("machine_max_jerk_y", 1); - optgroup->append_single_option_line("machine_max_jerk_z", 1); - optgroup->append_single_option_line("machine_max_jerk_e", 1); + append_option_line(optgroup, "machine_min_extruding_rate"); + append_option_line(optgroup, "machine_min_travel_rate"); + for (const std::string &axis : axes) { + append_option_line(optgroup, "machine_max_jerk_" + axis); + } return page; } From bfe78967099fd5fd21884a3b94095a7356ab1e1d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 22 Jun 2018 10:59:54 +0200 Subject: [PATCH 07/26] Try to fix uncorrect setup on Linux --- xs/src/slic3r/GUI/3DScene.cpp | 2 +- xs/src/slic3r/GUI/Field.cpp | 4 ++-- xs/src/slic3r/GUI/OptionsGroup.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 1879b30826..da7bfb812c 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1588,7 +1588,7 @@ bool _3DScene::LegendTexture::generate(const GCodePreviewData& preview_data, con m_data.clear(); // collects items to render - auto title = GUI::L_str(preview_data.get_legend_title()); + auto title = _(preview_data.get_legend_title()); const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors); unsigned int items_count = (unsigned int)items.size(); diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp index 46b04d959b..ba59225f6e 100644 --- a/xs/src/slic3r/GUI/Field.cpp +++ b/xs/src/slic3r/GUI/Field.cpp @@ -67,7 +67,7 @@ namespace Slic3r { namespace GUI { wxString Field::get_tooltip_text(const wxString& default_string) { wxString tooltip_text(""); - wxString tooltip = L_str(m_opt.tooltip); + wxString tooltip = _(m_opt.tooltip); if (tooltip.length() > 0) tooltip_text = tooltip + "(" + _(L("default")) + ": " + (boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") + @@ -355,7 +355,7 @@ void Choice::BUILD() { } else{ for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels){ - const wxString& str = m_opt_id == "support" ? L_str(el) : el; + const wxString& str = _(el);//m_opt_id == "support" ? _(el) : el; temp->Append(str); } set_selection(); diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 053293ee60..fc68564f2b 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -194,7 +194,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* ConfigOptionDef option = opt.opt; // add label if any if (option.label != "") { - wxString str_label = L_str(option.label); + wxString str_label = _(option.label); //! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1 // wxString str_label = (option.label == "Top" || option.label == "Bottom") ? // wxGETTEXT_IN_CONTEXT("Layers", wxString(option.label.c_str()): @@ -215,7 +215,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // add sidetext if any if (option.sidetext != "") { - auto sidetext = new wxStaticText(parent(), wxID_ANY, L_str(option.sidetext), wxDefaultPosition, wxDefaultSize); + auto sidetext = new wxStaticText(parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition, wxDefaultSize); sidetext->SetFont(sidetext_font); sizer->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); } @@ -237,7 +237,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* } Line OptionsGroup::create_single_option_line(const Option& option) const { - Line retval{ L_str(option.opt.label), L_str(option.opt.tooltip) }; + Line retval{ _(option.opt.label), _(option.opt.tooltip) }; Option tmp(option); tmp.opt.label = std::string(""); retval.append_option(tmp); From c10e9a6840dc99fcb02b1d0f493646e804b62a94 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 22 Jun 2018 12:27:56 +0200 Subject: [PATCH 08/26] Fixed crash-bug when close application after language changing --- xs/src/slic3r/GUI/GUI.cpp | 8 ++++++++ xs/src/slic3r/GUI/GUI.hpp | 2 ++ xs/xsp/GUI.xsp | 3 +++ 3 files changed, 13 insertions(+) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 1751f4548a..9fe45a3760 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -56,6 +56,7 @@ #include "../Utils/PresetUpdater.hpp" #include "../Config/Snapshot.hpp" +#include "3DScene.hpp" namespace Slic3r { namespace GUI { @@ -109,6 +110,7 @@ wxNotebook *g_wxTabPanel = nullptr; AppConfig *g_AppConfig = nullptr; PresetBundle *g_PresetBundle= nullptr; PresetUpdater *g_PresetUpdater = nullptr; +_3DScene *g_3DScene = nullptr; wxColour g_color_label_modified; wxColour g_color_label_sys; wxColour g_color_label_default; @@ -194,6 +196,11 @@ void set_preset_updater(PresetUpdater *updater) g_PresetUpdater = updater; } +void set_3DScene(_3DScene *scene) +{ + g_3DScene = scene; +} + std::vector& get_tabs_list() { return g_tabs_list; @@ -392,6 +399,7 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l save_language(); show_info(g_wxTabPanel, _(L("Application will be restarted")), _(L("Attention!"))); if (event_language_change > 0) { + g_3DScene->remove_all_canvases();// remove all canvas before recreate GUI wxCommandEvent event(event_language_change); g_wxApp->ProcessEvent(event); } diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 663815f68f..6b722a439a 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -32,6 +32,7 @@ class AppConfig; class PresetUpdater; class DynamicPrintConfig; class TabIface; +class _3DScene; #define _(s) Slic3r::translate((s)) inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); } @@ -87,6 +88,7 @@ void set_tab_panel(wxNotebook *tab_panel); void set_app_config(AppConfig *app_config); void set_preset_bundle(PresetBundle *preset_bundle); void set_preset_updater(PresetUpdater *updater); +void set_3DScene(_3DScene *scene); AppConfig* get_app_config(); wxApp* get_app(); diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index af0612f19a..6b05e9a67c 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -101,3 +101,6 @@ void desktop_open_datadir_folder() void fix_model_by_win10_sdk_gui(ModelObject *model_object_src, Print *print, Model *model_dst) %code%{ Slic3r::fix_model_by_win10_sdk_gui(*model_object_src, *print, *model_dst); %}; + +void set_3DScene(SV *scene) + %code%{ Slic3r::GUI::set_3DScene((_3DScene *)wxPli_sv_2_object(aTHX_ scene, "Slic3r::Model::3DScene") ); %}; From 3fdefbfbea324aa5940811a06b418290d966ecbd Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 22 Jun 2018 13:01:41 +0200 Subject: [PATCH 09/26] Added updatin of the "Machine limits" page according to "use silent mode" --- xs/src/slic3r/GUI/Tab.cpp | 57 ++++++++++++++++++++++----------------- xs/src/slic3r/GUI/Tab.hpp | 3 +++ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 583773c1e7..1703884348 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1631,8 +1631,14 @@ void TabPrinter::build() optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value){ wxTheApp->CallAfter([this, opt_key, value](){ - if (opt_key.compare("gcode_flavor") == 0) - build_extruder_pages(); + if (opt_key.compare("silent_mode") == 0) { + bool val = boost::any_cast(value); + if (m_use_silent_mode != val) { + m_rebuil_kinematics_page = true; + m_use_silent_mode = val; + } + } + build_extruder_pages(); update_dirty(); on_value_change(opt_key, value); }); @@ -1718,12 +1724,13 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){ on_value_change("extruders_count", extruders_count); } -void append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key) +void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key) { auto option = optgroup->get_option(opt_key, 0); auto line = Line{ option.opt.full_label, "" }; line.append_option(option); - line.append_option(optgroup->get_option(opt_key, 1)); + if (m_use_silent_mode) + line.append_option(optgroup->get_option(opt_key, 1)); optgroup->append_line(line); } @@ -1731,31 +1738,33 @@ PageShp TabPrinter::create_kinematics_page() { auto page = add_options_page(_(L("Machine limits")), "cog.png", true); - // Legend for OptionsGroups - auto optgroup = page->new_optgroup(_(L(""))); - optgroup->set_show_modified_btns_val(false); - optgroup->label_width = 230; - auto line = Line{ "", "" }; + if (m_use_silent_mode) { + // Legend for OptionsGroups + auto optgroup = page->new_optgroup(_(L(""))); + optgroup->set_show_modified_btns_val(false); + optgroup->label_width = 230; + auto line = Line{ "", "" }; - ConfigOptionDef def; - def.type = coString; - def.width = 150; - def.gui_type = "legend"; - def.tooltip = L("Values in this column are for Full Power mode"); - def.default_value = new ConfigOptionString{ L("Full Power")}; + ConfigOptionDef def; + def.type = coString; + def.width = 150; + def.gui_type = "legend"; + def.tooltip = L("Values in this column are for Full Power mode"); + def.default_value = new ConfigOptionString{ L("Full Power") }; - auto option = Option(def, "full_power_legend"); - line.append_option(option); + auto option = Option(def, "full_power_legend"); + line.append_option(option); - def.tooltip = L("Values in this column are for Silent mode"); - def.default_value = new ConfigOptionString{ L("Silent") }; - option = Option(def, "silent_legend"); - line.append_option(option); + def.tooltip = L("Values in this column are for Silent mode"); + def.default_value = new ConfigOptionString{ L("Silent") }; + option = Option(def, "silent_legend"); + line.append_option(option); - optgroup->append_line(line); + optgroup->append_line(line); + } std::vector axes{ "x", "y", "z", "e" }; - optgroup = page->new_optgroup(_(L("Maximum accelerations"))); + auto optgroup = page->new_optgroup(_(L("Maximum accelerations"))); for (const std::string &axis : axes) { append_option_line(optgroup, "machine_max_acceleration_" + axis); } @@ -1789,7 +1798,7 @@ void TabPrinter::build_extruder_pages() size_t existed_page = 0; for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) { - if (!is_marlin_flavor) + if (!is_marlin_flavor || m_rebuil_kinematics_page) m_pages.erase(m_pages.begin() + i); else existed_page = i; diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp index ab63bcc783..90bb40b9ed 100644 --- a/xs/src/slic3r/GUI/Tab.hpp +++ b/xs/src/slic3r/GUI/Tab.hpp @@ -313,6 +313,9 @@ public: class TabPrinter : public Tab { bool m_has_single_extruder_MM_page = false; + bool m_use_silent_mode = false; + void append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key); + bool m_rebuil_kinematics_page = false; public: wxButton* m_serial_test_btn; wxButton* m_octoprint_host_test_btn; From f420ced581a1ab7144dffa125d6b04fb1ae22f45 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 22 Jun 2018 14:01:27 +0200 Subject: [PATCH 10/26] Time estimators use initial data from config --- xs/src/libslic3r/GCode.cpp | 53 ++++++++++++++++++++++++++------ xs/src/libslic3r/GCode.hpp | 2 ++ xs/src/libslic3r/PrintConfig.hpp | 2 ++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index aa2b1399a2..c1798b0b54 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -375,7 +375,7 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ } fclose(file); - if (m_default_time_estimator.get_dialect() == gcfMarlin) + if (m_silent_time_estimator_enabled) GCodeTimeEstimator::post_process_elapsed_times(path_tmp, m_default_time_estimator.get_time(), m_silent_time_estimator.get_time()); if (! this->m_placeholder_parser_failed_templates.empty()) { @@ -410,12 +410,45 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) // resets time estimators m_default_time_estimator.reset(); m_default_time_estimator.set_dialect(print.config.gcode_flavor); - if (print.config.gcode_flavor == gcfMarlin) + m_default_time_estimator.set_acceleration(print.config.machine_max_acceleration_extruding.values[0]); + m_default_time_estimator.set_retract_acceleration(print.config.machine_max_acceleration_retracting.values[0]); + m_default_time_estimator.set_minimum_feedrate(print.config.machine_min_extruding_rate.values[0]); + m_default_time_estimator.set_minimum_travel_feedrate(print.config.machine_min_travel_rate.values[0]); + m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config.machine_max_acceleration_x.values[0]); + m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config.machine_max_acceleration_y.values[0]); + m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config.machine_max_acceleration_z.values[0]); + m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config.machine_max_acceleration_e.values[0]); + m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config.machine_max_feedrate_x.values[0]); + m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config.machine_max_feedrate_y.values[0]); + m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config.machine_max_feedrate_z.values[0]); + m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config.machine_max_feedrate_e.values[0]); + m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config.machine_max_jerk_x.values[0]); + m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config.machine_max_jerk_y.values[0]); + m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config.machine_max_jerk_z.values[0]); + m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config.machine_max_jerk_e.values[0]); + + m_silent_time_estimator_enabled = (print.config.gcode_flavor == gcfMarlin) && print.config.silent_mode; + if (m_silent_time_estimator_enabled) { m_silent_time_estimator.reset(); m_silent_time_estimator.set_dialect(print.config.gcode_flavor); + m_silent_time_estimator.set_acceleration(print.config.machine_max_acceleration_extruding.values[1]); + m_silent_time_estimator.set_retract_acceleration(print.config.machine_max_acceleration_retracting.values[1]); + m_silent_time_estimator.set_minimum_feedrate(print.config.machine_min_extruding_rate.values[1]); + m_silent_time_estimator.set_minimum_travel_feedrate(print.config.machine_min_travel_rate.values[1]); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config.machine_max_acceleration_x.values[1]); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config.machine_max_acceleration_y.values[1]); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config.machine_max_acceleration_z.values[1]); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config.machine_max_acceleration_e.values[1]); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config.machine_max_feedrate_x.values[1]); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config.machine_max_feedrate_y.values[1]); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config.machine_max_feedrate_z.values[1]); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config.machine_max_feedrate_e.values[1]); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config.machine_max_jerk_x.values[1]); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config.machine_max_jerk_y.values[1]); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config.machine_max_jerk_z.values[1]); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config.machine_max_jerk_e.values[1]); } - // resets analyzer m_analyzer.reset(); m_enable_analyzer = preview_data != nullptr; @@ -606,7 +639,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) } // before start gcode time estimation - if (m_default_time_estimator.get_dialect() == gcfMarlin) + if (m_silent_time_estimator_enabled) { _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); @@ -817,7 +850,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()), &config)); } // before end gcode time estimation - if (m_default_time_estimator.get_dialect() == gcfMarlin) + if (m_silent_time_estimator_enabled) { _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); @@ -829,7 +862,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) // calculates estimated printing time m_default_time_estimator.calculate_time(); - if (m_default_time_estimator.get_dialect() == gcfMarlin) + if (m_silent_time_estimator_enabled) m_silent_time_estimator.calculate_time(); // Get filament stats. @@ -839,7 +872,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) print.total_weight = 0.; print.total_cost = 0.; print.estimated_default_print_time = m_default_time_estimator.get_time_dhms(); - print.estimated_silent_print_time = (m_default_time_estimator.get_dialect() == gcfMarlin) ? m_silent_time_estimator.get_time_dhms() : "N/A"; + print.estimated_silent_print_time = m_silent_time_estimator_enabled ? m_silent_time_estimator.get_time_dhms() : "N/A"; for (const Extruder &extruder : m_writer.extruders()) { double used_filament = extruder.used_filament(); double extruded_volume = extruder.extruded_volume(); @@ -860,7 +893,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) } _write_format(file, "; total filament cost = %.1lf\n", print.total_cost); _write_format(file, "; estimated printing time (default mode) = %s\n", m_default_time_estimator.get_time_dhms().c_str()); - if (m_default_time_estimator.get_dialect() == gcfMarlin) + if (m_silent_time_estimator_enabled) _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); // Append full config. @@ -1430,7 +1463,7 @@ void GCode::process_layer( _write(file, gcode); // after layer time estimation - if (m_default_time_estimator.get_dialect() == gcfMarlin) + if (m_silent_time_estimator_enabled) { _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); @@ -2094,7 +2127,7 @@ void GCode::_write(FILE* file, const char *what) fwrite(gcode, 1, ::strlen(gcode), file); // updates time estimator and gcode lines vector m_default_time_estimator.add_gcode_block(gcode); - if (m_default_time_estimator.get_dialect() == gcfMarlin) + if (m_silent_time_estimator_enabled) m_silent_time_estimator.add_gcode_block(gcode); } } diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index b938604ef6..9fd31b9936 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -135,6 +135,7 @@ public: m_second_layer_things_done(false), m_default_time_estimator(GCodeTimeEstimator::Default), m_silent_time_estimator(GCodeTimeEstimator::Silent), + m_silent_time_estimator_enabled(false), m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())) {} ~GCode() {} @@ -294,6 +295,7 @@ protected: // Time estimators GCodeTimeEstimator m_default_time_estimator; GCodeTimeEstimator m_silent_time_estimator; + bool m_silent_time_estimator_enabled; // Analyzer GCodeAnalyzer m_analyzer; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index f3be03c2a3..b286186244 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -555,6 +555,7 @@ public: ConfigOptionFloat cooling_tube_retraction; ConfigOptionFloat cooling_tube_length; ConfigOptionFloat parking_pos_retraction; + ConfigOptionBool silent_mode; std::string get_extrusion_axis() const @@ -612,6 +613,7 @@ protected: OPT_PTR(cooling_tube_retraction); OPT_PTR(cooling_tube_length); OPT_PTR(parking_pos_retraction); + OPT_PTR(silent_mode); } }; From 54c90ee9488be6cac3df4d9fb6231fbd828a7059 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 22 Jun 2018 16:13:34 +0200 Subject: [PATCH 11/26] Updated PrintConfig default values for machine limits + fixed incorrect default value setting for the TextCtrl --- xs/src/libslic3r/PrintConfig.cpp | 28 ++++++++++++++-------------- xs/src/slic3r/GUI/Field.cpp | 32 +++++++++++++++++++++++--------- xs/src/slic3r/GUI/Field.hpp | 1 + xs/src/slic3r/GUI/Tab.cpp | 4 ++-- xs/src/slic3r/GUI/Tab.hpp | 2 +- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 68fc2da244..a59a835f4a 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -861,7 +861,7 @@ PrintConfigDef::PrintConfigDef() def->tooltip = L("Set silent mode for the G-code flavor"); def->default_value = new ConfigOptionBool(true); - const int machine_linits_opt_width = 70; + const int machine_limits_opt_width = 70; { struct AxisDefault { std::string name; @@ -871,10 +871,10 @@ PrintConfigDef::PrintConfigDef() }; std::vector axes { // name, max_feedrate, max_acceleration, max_jerk - { "x", { 200., 200. }, { 1000., 1000. }, { 10., 10. } }, - { "y", { 200., 200. }, { 1000., 1000. }, { 10., 10. } }, - { "z", { 12., 12. }, { 200., 200. }, { 0.4, 0.4 } }, - { "e", { 120., 120. }, { 5000., 5000. }, { 2.5, 2.5 } } + { "x", { 500., 200. }, { 9000., 1000. }, { 10., 10. } }, + { "y", { 500., 200. }, { 9000., 1000. }, { 10., 10. } }, + { "z", { 12., 12. }, { 500., 200. }, { 0.2, 0.4 } }, + { "e", { 120., 120. }, { 10000., 5000. }, { 2.5, 2.5 } } }; for (const AxisDefault &axis : axes) { std::string axis_upper = boost::to_upper_copy(axis.name); @@ -885,7 +885,7 @@ PrintConfigDef::PrintConfigDef() def->tooltip = (boost::format(L("Maximum feedrate of the %1% axis")) % axis_upper).str(); def->sidetext = L("mm/s"); def->min = 0; - def->width = machine_linits_opt_width; + def->width = machine_limits_opt_width; def->default_value = new ConfigOptionFloats(axis.max_feedrate); // Add the machine acceleration limits for XYZE axes (M201) def = this->add("machine_max_acceleration_" + axis.name, coFloats); @@ -894,7 +894,7 @@ PrintConfigDef::PrintConfigDef() def->tooltip = (boost::format(L("Maximum acceleration of the %1% axis")) % axis_upper).str(); def->sidetext = L("mm/s²"); def->min = 0; - def->width = machine_linits_opt_width; + def->width = machine_limits_opt_width; def->default_value = new ConfigOptionFloats(axis.max_acceleration); // Add the machine jerk limits for XYZE axes (M205) def = this->add("machine_max_jerk_" + axis.name, coFloats); @@ -903,7 +903,7 @@ PrintConfigDef::PrintConfigDef() def->tooltip = (boost::format(L("Maximum jerk of the %1% axis")) % axis_upper).str(); def->sidetext = L("mm/s"); def->min = 0; - def->width = machine_linits_opt_width; + def->width = machine_limits_opt_width; def->default_value = new ConfigOptionFloats(axis.max_jerk); } } @@ -915,7 +915,7 @@ PrintConfigDef::PrintConfigDef() def->tooltip = L("Minimum feedrate when extruding") + " (M205 S)"; def->sidetext = L("mm/s"); def->min = 0; - def->width = machine_linits_opt_width; + def->width = machine_limits_opt_width; def->default_value = new ConfigOptionFloats{ 0., 0. }; // M205 T... [mm/sec] @@ -925,7 +925,7 @@ PrintConfigDef::PrintConfigDef() def->tooltip = L("Minimum travel feedrate") + " (M205 T)"; def->sidetext = L("mm/s"); def->min = 0; - def->width = machine_linits_opt_width; + def->width = machine_limits_opt_width; def->default_value = new ConfigOptionFloats{ 0., 0. }; // M204 S... [mm/sec^2] @@ -935,8 +935,8 @@ PrintConfigDef::PrintConfigDef() def->tooltip = L("Maximum acceleration when extruding") + " (M204 S)"; def->sidetext = L("mm/s²"); def->min = 0; - def->width = machine_linits_opt_width; - def->default_value = new ConfigOptionFloats(1250., 1250.); + def->width = machine_limits_opt_width; + def->default_value = new ConfigOptionFloats(1500., 1250.); // M204 T... [mm/sec^2] def = this->add("machine_max_acceleration_retracting", coFloats); @@ -945,8 +945,8 @@ PrintConfigDef::PrintConfigDef() def->tooltip = L("Maximum acceleration when retracting") + " (M204 T)"; def->sidetext = L("mm/s²"); def->min = 0; - def->width = machine_linits_opt_width; - def->default_value = new ConfigOptionFloats(1250., 1250.); + def->width = machine_limits_opt_width; + def->default_value = new ConfigOptionFloats(1500., 1250.); def = this->add("max_fan_speed", coInts); def->label = L("Max"); diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp index ba59225f6e..57420a4112 100644 --- a/xs/src/slic3r/GUI/Field.cpp +++ b/xs/src/slic3r/GUI/Field.cpp @@ -35,6 +35,22 @@ namespace Slic3r { namespace GUI { set_undo_bitmap(&bmp); set_undo_to_sys_bitmap(&bmp); + switch (m_opt.type) + { + case coPercents: + case coFloats: + case coStrings: + case coBools: + case coInts: { + auto tag_pos = m_opt_id.find("#"); + if (tag_pos != std::string::npos) + m_opt_idx = stoi(m_opt_id.substr(tag_pos + 1, m_opt_id.size())); + break; + } + default: + break; + } + BUILD(); } @@ -151,10 +167,10 @@ namespace Slic3r { namespace GUI { case coFloat: { double val = m_opt.type == coFloats ? - static_cast(m_opt.default_value)->get_at(0) : + static_cast(m_opt.default_value)->get_at(m_opt_idx) : m_opt.type == coFloat ? m_opt.default_value->getFloat() : - static_cast(m_opt.default_value)->get_at(0); + static_cast(m_opt.default_value)->get_at(m_opt_idx); text_value = double_to_string(val); break; } @@ -164,10 +180,8 @@ namespace Slic3r { namespace GUI { case coStrings: { const ConfigOptionStrings *vec = static_cast(m_opt.default_value); - if (vec == nullptr || vec->empty()) break; - if (vec->size() > 1) - break; - text_value = vec->values.at(0); + if (vec == nullptr || vec->empty()) break; //for the case of empty default value + text_value = vec->get_at(m_opt_idx); break; } default: @@ -249,7 +263,7 @@ void CheckBox::BUILD() { bool check_value = m_opt.type == coBool ? m_opt.default_value->getBool() : m_opt.type == coBools ? - static_cast(m_opt.default_value)->values.at(0) : + static_cast(m_opt.default_value)->get_at(m_opt_idx) : false; auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); @@ -408,7 +422,7 @@ void Choice::set_selection() break; } case coStrings:{ - text_value = static_cast(m_opt.default_value)->values.at(0); + text_value = static_cast(m_opt.default_value)->get_at(m_opt_idx); size_t idx = 0; for (auto el : m_opt.enum_values) @@ -572,7 +586,7 @@ void ColourPicker::BUILD() if (m_opt.height >= 0) size.SetHeight(m_opt.height); if (m_opt.width >= 0) size.SetWidth(m_opt.width); - wxString clr(static_cast(m_opt.default_value)->values.at(0)); + wxString clr(static_cast(m_opt.default_value)->get_at(m_opt_idx)); auto temp = new wxColourPickerCtrl(m_parent, wxID_ANY, clr, wxDefaultPosition, size); // // recast as a wxWindow to fit the calling convention diff --git a/xs/src/slic3r/GUI/Field.hpp b/xs/src/slic3r/GUI/Field.hpp index fb6116b79c..db8d2a4085 100644 --- a/xs/src/slic3r/GUI/Field.hpp +++ b/xs/src/slic3r/GUI/Field.hpp @@ -95,6 +95,7 @@ public: /// Copy of ConfigOption for deduction purposes const ConfigOptionDef m_opt {ConfigOptionDef()}; const t_config_option_key m_opt_id;//! {""}; + int m_opt_idx = 0; /// Sets a value for this control. /// subclasses should overload with a specific version diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 1703884348..4935d8dcde 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1734,7 +1734,7 @@ void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::s optgroup->append_line(line); } -PageShp TabPrinter::create_kinematics_page() +PageShp TabPrinter::build_kinematics_page() { auto page = add_options_page(_(L("Machine limits")), "cog.png", true); @@ -1806,7 +1806,7 @@ void TabPrinter::build_extruder_pages() } if (existed_page < n_before_extruders && is_marlin_flavor){ - auto page = create_kinematics_page(); + auto page = build_kinematics_page(); m_pages.insert(m_pages.begin() + n_before_extruders, page); } diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp index 90bb40b9ed..4906b8d1ef 100644 --- a/xs/src/slic3r/GUI/Tab.hpp +++ b/xs/src/slic3r/GUI/Tab.hpp @@ -333,7 +333,7 @@ public: void update() override; void update_serial_ports(); void extruders_count_changed(size_t extruders_count); - PageShp create_kinematics_page(); + PageShp build_kinematics_page(); void build_extruder_pages(); void on_preset_loaded() override; void init_options_list() override; From f9b85b67009ae7b7e65154e9e0485847110b4858 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 25 Jun 2018 16:03:43 +0200 Subject: [PATCH 12/26] Correct updating of "Machine limits" and "Single extruder MM setup" pages --- xs/src/slic3r/GUI/Tab.cpp | 11 ++++++++--- xs/src/slic3r/GUI/Tab.hpp | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 4935d8dcde..cf1b84639b 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1634,7 +1634,7 @@ void TabPrinter::build() if (opt_key.compare("silent_mode") == 0) { bool val = boost::any_cast(value); if (m_use_silent_mode != val) { - m_rebuil_kinematics_page = true; + m_rebuild_kinematics_page = true; m_use_silent_mode = val; } } @@ -1798,7 +1798,7 @@ void TabPrinter::build_extruder_pages() size_t existed_page = 0; for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) { - if (!is_marlin_flavor || m_rebuil_kinematics_page) + if (!is_marlin_flavor || m_rebuild_kinematics_page) m_pages.erase(m_pages.begin() + i); else existed_page = i; @@ -1922,6 +1922,10 @@ void TabPrinter::update(){ bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; get_field("silent_mode")->toggle(is_marlin_flavor); + if (m_use_silent_mode != m_config->opt_bool("silent_mode")) { + m_rebuild_kinematics_page = true; + m_use_silent_mode = m_config->opt_bool("silent_mode"); + } for (size_t i = 0; i < m_extruders_count; ++i) { bool have_retract_length = m_config->opt_float("retract_length", i) > 0; @@ -2039,7 +2043,8 @@ void Tab::rebuild_page_tree() auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID()); m_treectrl->SetItemTextColour(itemId, p->get_item_colour()); if (p->title() == selected) { - m_disable_tree_sel_changed_event = 1; + if (!(p->title() == _(L("Machine limits")) || p->title() == _(L("Single extruder MM setup")))) // These Pages have to be updated inside OnTreeSelChange + m_disable_tree_sel_changed_event = 1; m_treectrl->SelectItem(itemId); m_disable_tree_sel_changed_event = 0; have_selection = 1; diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp index 4906b8d1ef..9045a5182b 100644 --- a/xs/src/slic3r/GUI/Tab.hpp +++ b/xs/src/slic3r/GUI/Tab.hpp @@ -315,7 +315,7 @@ class TabPrinter : public Tab bool m_has_single_extruder_MM_page = false; bool m_use_silent_mode = false; void append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key); - bool m_rebuil_kinematics_page = false; + bool m_rebuild_kinematics_page = false; public: wxButton* m_serial_test_btn; wxButton* m_octoprint_host_test_btn; From 7ff22b941343bd8f3aabed43d75fb64b9ff5abab Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 27 Jun 2018 15:35:47 +0200 Subject: [PATCH 13/26] Time estimate emitted to gcode at requested interval --- lib/Slic3r/GUI/Plater.pm | 10 +- xs/src/libslic3r/GCode.cpp | 157 ++++++--- xs/src/libslic3r/GCode.hpp | 10 +- xs/src/libslic3r/GCodeTimeEstimator.cpp | 418 +++++++++++++++++++----- xs/src/libslic3r/GCodeTimeEstimator.hpp | 67 +++- xs/src/libslic3r/Print.hpp | 5 +- xs/src/libslic3r/PrintConfig.cpp | 10 +- xs/xsp/Print.xsp | 4 +- 8 files changed, 544 insertions(+), 137 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 330ec69d50..9422da3548 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -509,7 +509,10 @@ sub new { fil_mm3 => L("Used Filament (mm³)"), fil_g => L("Used Filament (g)"), cost => L("Cost"), - default_time => L("Estimated printing time (default mode)"), +#========================================================================================================================================== + normal_time => L("Estimated printing time (normal mode)"), +# default_time => L("Estimated printing time (default mode)"), +#========================================================================================================================================== silent_time => L("Estimated printing time (silent mode)"), ); while (my $field = shift @info) { @@ -1578,7 +1581,10 @@ sub on_export_completed { $self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost)); $self->{"print_info_fil_g"}->SetLabel(sprintf("%.2f" , $self->{print}->total_weight)); $self->{"print_info_fil_mm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume)); - $self->{"print_info_default_time"}->SetLabel($self->{print}->estimated_default_print_time); +#========================================================================================================================================== + $self->{"print_info_normal_time"}->SetLabel($self->{print}->estimated_normal_print_time); +# $self->{"print_info_default_time"}->SetLabel($self->{print}->estimated_default_print_time); +#========================================================================================================================================== $self->{"print_info_silent_time"}->SetLabel($self->{print}->estimated_silent_print_time); $self->{"print_info_fil_m"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament / 1000)); $self->{"print_info_box_show"}->(1); diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index c1798b0b54..1f0aac816a 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -375,8 +375,15 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ } fclose(file); +//################################################################################################################# + m_normal_time_estimator.post_process_remaining_times(path_tmp, 60.0f); +//################################################################################################################# + if (m_silent_time_estimator_enabled) - GCodeTimeEstimator::post_process_elapsed_times(path_tmp, m_default_time_estimator.get_time(), m_silent_time_estimator.get_time()); +//############################################################################################################3 + m_silent_time_estimator.post_process_remaining_times(path_tmp, 60.0f); +// GCodeTimeEstimator::post_process_elapsed_times(path_tmp, m_default_time_estimator.get_time(), m_silent_time_estimator.get_time()); +//############################################################################################################3 if (! this->m_placeholder_parser_failed_templates.empty()) { // G-code export proceeded, but some of the PlaceholderParser substitutions failed. @@ -408,30 +415,72 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) PROFILE_FUNC(); // resets time estimators - m_default_time_estimator.reset(); - m_default_time_estimator.set_dialect(print.config.gcode_flavor); - m_default_time_estimator.set_acceleration(print.config.machine_max_acceleration_extruding.values[0]); - m_default_time_estimator.set_retract_acceleration(print.config.machine_max_acceleration_retracting.values[0]); - m_default_time_estimator.set_minimum_feedrate(print.config.machine_min_extruding_rate.values[0]); - m_default_time_estimator.set_minimum_travel_feedrate(print.config.machine_min_travel_rate.values[0]); - m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config.machine_max_acceleration_x.values[0]); - m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config.machine_max_acceleration_y.values[0]); - m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config.machine_max_acceleration_z.values[0]); - m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config.machine_max_acceleration_e.values[0]); - m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config.machine_max_feedrate_x.values[0]); - m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config.machine_max_feedrate_y.values[0]); - m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config.machine_max_feedrate_z.values[0]); - m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config.machine_max_feedrate_e.values[0]); - m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config.machine_max_jerk_x.values[0]); - m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config.machine_max_jerk_y.values[0]); - m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config.machine_max_jerk_z.values[0]); - m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config.machine_max_jerk_e.values[0]); +//####################################################################################################################################################################### + m_normal_time_estimator.reset(); + m_normal_time_estimator.set_dialect(print.config.gcode_flavor); + m_normal_time_estimator.set_remaining_times_enabled(false); + m_normal_time_estimator.set_acceleration(print.config.machine_max_acceleration_extruding.values[0]); + m_normal_time_estimator.set_retract_acceleration(print.config.machine_max_acceleration_retracting.values[0]); + m_normal_time_estimator.set_minimum_feedrate(print.config.machine_min_extruding_rate.values[0]); + m_normal_time_estimator.set_minimum_travel_feedrate(print.config.machine_min_travel_rate.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config.machine_max_acceleration_x.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config.machine_max_acceleration_y.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config.machine_max_acceleration_z.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config.machine_max_acceleration_e.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config.machine_max_feedrate_x.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config.machine_max_feedrate_y.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config.machine_max_feedrate_z.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config.machine_max_feedrate_e.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config.machine_max_jerk_x.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config.machine_max_jerk_y.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config.machine_max_jerk_z.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config.machine_max_jerk_e.values[0]); + + std::cout << "Normal" << std::endl; + std::cout << "set_acceleration " << print.config.machine_max_acceleration_extruding.values[0] << std::endl; + std::cout << "set_retract_acceleration " << print.config.machine_max_acceleration_retracting.values[0] << std::endl; + std::cout << "set_minimum_feedrate " << print.config.machine_min_extruding_rate.values[0] << std::endl; + std::cout << "set_minimum_travel_feedrate " << print.config.machine_min_travel_rate.values[0] << std::endl; + std::cout << "set_axis_max_acceleration X " << print.config.machine_max_acceleration_x.values[0] << std::endl; + std::cout << "set_axis_max_acceleration Y " << print.config.machine_max_acceleration_y.values[0] << std::endl; + std::cout << "set_axis_max_acceleration Z " << print.config.machine_max_acceleration_z.values[0] << std::endl; + std::cout << "set_axis_max_acceleration E " << print.config.machine_max_acceleration_e.values[0] << std::endl; + std::cout << "set_axis_max_feedrate X " << print.config.machine_max_feedrate_x.values[0] << std::endl; + std::cout << "set_axis_max_feedrate Y " << print.config.machine_max_feedrate_y.values[0] << std::endl; + std::cout << "set_axis_max_feedrate Z " << print.config.machine_max_feedrate_z.values[0] << std::endl; + std::cout << "set_axis_max_feedrate E " << print.config.machine_max_feedrate_e.values[0] << std::endl; + std::cout << "set_axis_max_jerk X " << print.config.machine_max_jerk_x.values[0] << std::endl; + std::cout << "set_axis_max_jerk Y " << print.config.machine_max_jerk_y.values[0] << std::endl; + std::cout << "set_axis_max_jerk Z " << print.config.machine_max_jerk_z.values[0] << std::endl; + std::cout << "set_axis_max_jerk E " << print.config.machine_max_jerk_e.values[0] << std::endl; + + +// m_default_time_estimator.reset(); +// m_default_time_estimator.set_dialect(print.config.gcode_flavor); +// m_default_time_estimator.set_acceleration(print.config.machine_max_acceleration_extruding.values[0]); +// m_default_time_estimator.set_retract_acceleration(print.config.machine_max_acceleration_retracting.values[0]); +// m_default_time_estimator.set_minimum_feedrate(print.config.machine_min_extruding_rate.values[0]); +// m_default_time_estimator.set_minimum_travel_feedrate(print.config.machine_min_travel_rate.values[0]); +// m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config.machine_max_acceleration_x.values[0]); +// m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config.machine_max_acceleration_y.values[0]); +// m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config.machine_max_acceleration_z.values[0]); +// m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config.machine_max_acceleration_e.values[0]); +// m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config.machine_max_feedrate_x.values[0]); +// m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config.machine_max_feedrate_y.values[0]); +// m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config.machine_max_feedrate_z.values[0]); +// m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config.machine_max_feedrate_e.values[0]); +// m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config.machine_max_jerk_x.values[0]); +// m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config.machine_max_jerk_y.values[0]); +// m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config.machine_max_jerk_z.values[0]); +// m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config.machine_max_jerk_e.values[0]); +//####################################################################################################################################################################### m_silent_time_estimator_enabled = (print.config.gcode_flavor == gcfMarlin) && print.config.silent_mode; if (m_silent_time_estimator_enabled) { m_silent_time_estimator.reset(); m_silent_time_estimator.set_dialect(print.config.gcode_flavor); + m_silent_time_estimator.set_remaining_times_enabled(false); m_silent_time_estimator.set_acceleration(print.config.machine_max_acceleration_extruding.values[1]); m_silent_time_estimator.set_retract_acceleration(print.config.machine_max_acceleration_retracting.values[1]); m_silent_time_estimator.set_minimum_feedrate(print.config.machine_min_extruding_rate.values[1]); @@ -638,12 +687,14 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) _writeln(file, buf); } - // before start gcode time estimation - if (m_silent_time_estimator_enabled) - { - _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); - _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); - } +//####################################################################################################################################################################### +// // before start gcode time estimation +// if (m_silent_time_estimator_enabled) +// { +// _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); +// _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); +// } +//####################################################################################################################################################################### // Write the custom start G-code _writeln(file, start_gcode); @@ -849,21 +900,34 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) for (const std::string &end_gcode : print.config.end_filament_gcode.values) _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()), &config)); } - // before end gcode time estimation - if (m_silent_time_estimator_enabled) - { - _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); - _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); - } +//####################################################################################################################################################################### +// // before end gcode time estimation +// if (m_silent_time_estimator_enabled) +// { +// _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); +// _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); +// } +//####################################################################################################################################################################### _writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id(), &config)); } _write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% _write(file, m_writer.postamble()); // calculates estimated printing time - m_default_time_estimator.calculate_time(); +//####################################################################################################################################################################### + m_normal_time_estimator.set_remaining_times_enabled(true); + m_normal_time_estimator.calculate_time(); +// m_default_time_estimator.calculate_time(); +//####################################################################################################################################################################### if (m_silent_time_estimator_enabled) +//####################################################################################################################################################################### + { + m_silent_time_estimator.set_remaining_times_enabled(true); +//####################################################################################################################################################################### m_silent_time_estimator.calculate_time(); +//####################################################################################################################################################################### + } +//####################################################################################################################################################################### // Get filament stats. print.filament_stats.clear(); @@ -871,7 +935,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) print.total_extruded_volume = 0.; print.total_weight = 0.; print.total_cost = 0.; - print.estimated_default_print_time = m_default_time_estimator.get_time_dhms(); +//####################################################################################################################################################################### + print.estimated_normal_print_time = m_normal_time_estimator.get_time_dhms(); +// print.estimated_default_print_time = m_default_time_estimator.get_time_dhms(); +//####################################################################################################################################################################### print.estimated_silent_print_time = m_silent_time_estimator_enabled ? m_silent_time_estimator.get_time_dhms() : "N/A"; for (const Extruder &extruder : m_writer.extruders()) { double used_filament = extruder.used_filament(); @@ -892,7 +959,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) print.total_extruded_volume = print.total_extruded_volume + extruded_volume; } _write_format(file, "; total filament cost = %.1lf\n", print.total_cost); - _write_format(file, "; estimated printing time (default mode) = %s\n", m_default_time_estimator.get_time_dhms().c_str()); +//####################################################################################################################################################################### + _write_format(file, "; estimated printing time (normal mode) = %s\n", m_normal_time_estimator.get_time_dhms().c_str()); +// _write_format(file, "; estimated printing time (default mode) = %s\n", m_default_time_estimator.get_time_dhms().c_str()); +//####################################################################################################################################################################### if (m_silent_time_estimator_enabled) _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); @@ -1462,12 +1532,14 @@ void GCode::process_layer( _write(file, gcode); - // after layer time estimation - if (m_silent_time_estimator_enabled) - { - _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); - _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); - } +//####################################################################################################################################################################### +// // after layer time estimation +// if (m_silent_time_estimator_enabled) +// { +// _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); +// _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); +// } +//####################################################################################################################################################################### } void GCode::apply_print_config(const PrintConfig &print_config) @@ -2126,7 +2198,10 @@ void GCode::_write(FILE* file, const char *what) // writes string to file fwrite(gcode, 1, ::strlen(gcode), file); // updates time estimator and gcode lines vector - m_default_time_estimator.add_gcode_block(gcode); +//####################################################################################################################################################################### + m_normal_time_estimator.add_gcode_block(gcode); +// m_default_time_estimator.add_gcode_block(gcode); +//####################################################################################################################################################################### if (m_silent_time_estimator_enabled) m_silent_time_estimator.add_gcode_block(gcode); } diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index 9fd31b9936..d994e750f5 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -133,7 +133,10 @@ public: m_last_height(GCodeAnalyzer::Default_Height), m_brim_done(false), m_second_layer_things_done(false), - m_default_time_estimator(GCodeTimeEstimator::Default), +//############################################################################################################3 + m_normal_time_estimator(GCodeTimeEstimator::Normal), +// m_default_time_estimator(GCodeTimeEstimator::Default), +//############################################################################################################3 m_silent_time_estimator(GCodeTimeEstimator::Silent), m_silent_time_estimator_enabled(false), m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())) @@ -293,7 +296,10 @@ protected: std::pair m_last_obj_copy; // Time estimators - GCodeTimeEstimator m_default_time_estimator; +//############################################################################################################3 + GCodeTimeEstimator m_normal_time_estimator; +// GCodeTimeEstimator m_default_time_estimator; +//############################################################################################################3 GCodeTimeEstimator m_silent_time_estimator; bool m_silent_time_estimator_enabled; diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index ad82c6820f..8f306835fd 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -12,15 +12,26 @@ static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float MILLISEC_TO_SEC = 0.001f; static const float INCHES_TO_MM = 25.4f; -static const float DEFAULT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) -static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 -static const float DEFAULT_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 -static const float DEFAULT_AXIS_MAX_FEEDRATE[] = { 500.0f, 500.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK2 -static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f, 10000.0f }; // Prusa Firmware 1_75mm_MK2 -static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from Prusa Firmware (Configuration.h) -static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) -static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) -static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent +//####################################################################################################################################################################### +static const float NORMAL_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) +static const float NORMAL_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 +static const float NORMAL_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 +static const float NORMAL_AXIS_MAX_FEEDRATE[] = { 500.0f, 500.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK2 +static const float NORMAL_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f, 10000.0f }; // Prusa Firmware 1_75mm_MK2 +static const float NORMAL_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.4f, 2.5f }; // from Prusa Firmware (Configuration.h) +static const float NORMAL_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +static const float NORMAL_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +static const float NORMAL_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent +//static const float DEFAULT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) +//static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 +//static const float DEFAULT_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 +//static const float DEFAULT_AXIS_MAX_FEEDRATE[] = { 500.0f, 500.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK2 +//static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f, 10000.0f }; // Prusa Firmware 1_75mm_MK2 +//static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from Prusa Firmware (Configuration.h) +//static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +//static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +//static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent +//####################################################################################################################################################################### static const float SILENT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) static const float SILENT_ACCELERATION = 1250.0f; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full @@ -34,10 +45,12 @@ static const float SILENT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 perc static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; -static const std::string ELAPSED_TIME_TAG_DEFAULT = ";_ELAPSED_TIME_DEFAULT: "; -static const std::string ELAPSED_TIME_TAG_SILENT = ";_ELAPSED_TIME_SILENT: "; - -static const std::string REMAINING_TIME_CMD = "M73"; +//############################################################################################################3 +//static const std::string ELAPSED_TIME_TAG_DEFAULT = ";_ELAPSED_TIME_DEFAULT: "; +//static const std::string ELAPSED_TIME_TAG_SILENT = ";_ELAPSED_TIME_SILENT: "; +// +//static const std::string REMAINING_TIME_CMD = "M73"; +//############################################################################################################3 #if ENABLE_MOVE_STATS static const std::string MOVE_TYPE_STR[Slic3r::GCodeTimeEstimator::Block::Num_Types] = @@ -93,8 +106,19 @@ namespace Slic3r { return ::sqrt(value); } +//################################################################################################################# + GCodeTimeEstimator::Block::Time::Time() + : elapsed(-1.0f) + , remaining(-1.0f) + { + } +//################################################################################################################# + GCodeTimeEstimator::Block::Block() : st_synchronized(false) +//################################################################################################################# + , g1_line_id(0) +//################################################################################################################# { } @@ -159,6 +183,13 @@ namespace Slic3r { trapezoid.decelerate_after = accelerate_distance + cruise_distance; } +//################################################################################################################# + void GCodeTimeEstimator::Block::calculate_remaining_time(float final_time) + { + time.remaining = (time.elapsed >= 0.0f) ? final_time - time.elapsed : -1.0f; + } +//################################################################################################################# + float GCodeTimeEstimator::Block::max_allowable_speed(float acceleration, float target_velocity, float distance) { // to avoid invalid negative numbers due to numerical imprecision @@ -217,6 +248,10 @@ namespace Slic3r { _reset_time(); _set_blocks_st_synchronize(false); _calculate_time(); +//################################################################################################################# + if (are_remaining_times_enabled()) + _calculate_remaining_times(); +//################################################################################################################# #if ENABLE_MOVE_STATS _log_moves_stats(); @@ -265,82 +300,180 @@ namespace Slic3r { #endif // ENABLE_MOVE_STATS } - std::string GCodeTimeEstimator::get_elapsed_time_string() - { - calculate_time(); - switch (_mode) - { - default: - case Default: - return ELAPSED_TIME_TAG_DEFAULT + std::to_string(get_time()) + "\n"; - case Silent: - return ELAPSED_TIME_TAG_SILENT + std::to_string(get_time()) + "\n"; - } - } +//############################################################################################################3 +// std::string GCodeTimeEstimator::get_elapsed_time_string() +// { +// calculate_time(); +// switch (_mode) +// { +// default: +// case Default: +// return ELAPSED_TIME_TAG_DEFAULT + std::to_string(get_time()) + "\n"; +// case Silent: +// return ELAPSED_TIME_TAG_SILENT + std::to_string(get_time()) + "\n"; +// } +// } +// +// bool GCodeTimeEstimator::post_process_elapsed_times(const std::string& filename, float default_time, float silent_time) +// { +// boost::nowide::ifstream in(filename); +// if (!in.good()) +// throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for reading.\n")); +// +// std::string path_tmp = filename + ".times"; +// +// FILE* out = boost::nowide::fopen(path_tmp.c_str(), "wb"); +// if (out == nullptr) +// throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for writing.\n")); +// +// std::string line; +// while (std::getline(in, line)) +// { +// if (!in.good()) +// { +// fclose(out); +// throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n")); +// } +// +// // this function expects elapsed time for default and silent mode to be into two consecutive lines inside the gcode +// if (boost::contains(line, ELAPSED_TIME_TAG_DEFAULT)) +// { +// std::string default_elapsed_time_str = line.substr(ELAPSED_TIME_TAG_DEFAULT.length()); +// float elapsed_time = (float)atof(default_elapsed_time_str.c_str()); +// float remaining_time = default_time - elapsed_time; +// line = REMAINING_TIME_CMD + " P" + std::to_string((int)(100.0f * elapsed_time / default_time)); +// line += " R" + _get_time_minutes(remaining_time); +// +// std::string next_line; +// std::getline(in, next_line); +// if (!in.good()) +// { +// fclose(out); +// throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n")); +// } +// +// if (boost::contains(next_line, ELAPSED_TIME_TAG_SILENT)) +// { +// std::string silent_elapsed_time_str = next_line.substr(ELAPSED_TIME_TAG_SILENT.length()); +// float elapsed_time = (float)atof(silent_elapsed_time_str.c_str()); +// float remaining_time = silent_time - elapsed_time; +// line += " Q" + std::to_string((int)(100.0f * elapsed_time / silent_time)); +// line += " S" + _get_time_minutes(remaining_time); +// } +// else +// // found horphaned default elapsed time, skip the remaining time line output +// line = next_line; +// } +// else if (boost::contains(line, ELAPSED_TIME_TAG_SILENT)) +// // found horphaned silent elapsed time, skip the remaining time line output +// continue; +// +// line += "\n"; +// fwrite((const void*)line.c_str(), 1, line.length(), out); +// if (ferror(out)) +// { +// in.close(); +// fclose(out); +// boost::nowide::remove(path_tmp.c_str()); +// throw std::runtime_error(std::string("Remaining times estimation failed.\nIs the disk full?\n")); +// } +// } +// +// fclose(out); +// in.close(); +// +// boost::nowide::remove(filename.c_str()); +// if (boost::nowide::rename(path_tmp.c_str(), filename.c_str()) != 0) +// throw std::runtime_error(std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + filename + '\n' + +// "Is " + path_tmp + " locked?" + '\n'); +// +// return true; +// } +//############################################################################################################3 - bool GCodeTimeEstimator::post_process_elapsed_times(const std::string& filename, float default_time, float silent_time) +//################################################################################################################# + bool GCodeTimeEstimator::post_process_remaining_times(const std::string& filename, float interval) { boost::nowide::ifstream in(filename); if (!in.good()) - throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for reading.\n")); + throw std::runtime_error(std::string("Remaining times export failed.\nCannot open file for reading.\n")); std::string path_tmp = filename + ".times"; FILE* out = boost::nowide::fopen(path_tmp.c_str(), "wb"); if (out == nullptr) - throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for writing.\n")); + throw std::runtime_error(std::string("Remaining times export failed.\nCannot open file for writing.\n")); - std::string line; - while (std::getline(in, line)) + std::string time_mask; + switch (_mode) + { + default: + case Normal: + { + time_mask = "M73 P%s R%s\n"; + break; + } + case Silent: + { + time_mask = "M73 Q%s S%s\n"; + break; + } + } + + unsigned int g1_lines_count = 0; + float last_recorded_time = _time; + std::string gcode_line; + while (std::getline(in, gcode_line)) { if (!in.good()) { fclose(out); - throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n")); + throw std::runtime_error(std::string("Remaining times export failed.\nError while reading from file.\n")); } - // this function expects elapsed time for default and silent mode to be into two consecutive lines inside the gcode - if (boost::contains(line, ELAPSED_TIME_TAG_DEFAULT)) - { - std::string default_elapsed_time_str = line.substr(ELAPSED_TIME_TAG_DEFAULT.length()); - float elapsed_time = (float)atof(default_elapsed_time_str.c_str()); - float remaining_time = default_time - elapsed_time; - line = REMAINING_TIME_CMD + " P" + std::to_string((int)(100.0f * elapsed_time / default_time)); - line += " R" + _get_time_minutes(remaining_time); - - std::string next_line; - std::getline(in, next_line); - if (!in.good()) - { - fclose(out); - throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n")); - } - - if (boost::contains(next_line, ELAPSED_TIME_TAG_SILENT)) - { - std::string silent_elapsed_time_str = next_line.substr(ELAPSED_TIME_TAG_SILENT.length()); - float elapsed_time = (float)atof(silent_elapsed_time_str.c_str()); - float remaining_time = silent_time - elapsed_time; - line += " Q" + std::to_string((int)(100.0f * elapsed_time / silent_time)); - line += " S" + _get_time_minutes(remaining_time); - } - else - // found horphaned default elapsed time, skip the remaining time line output - line = next_line; - } - else if (boost::contains(line, ELAPSED_TIME_TAG_SILENT)) - // found horphaned silent elapsed time, skip the remaining time line output - continue; - - line += "\n"; - fwrite((const void*)line.c_str(), 1, line.length(), out); + // saves back the line + gcode_line += "\n"; + fwrite((const void*)gcode_line.c_str(), 1, gcode_line.length(), out); if (ferror(out)) { in.close(); fclose(out); boost::nowide::remove(path_tmp.c_str()); - throw std::runtime_error(std::string("Remaining times estimation failed.\nIs the disk full?\n")); + throw std::runtime_error(std::string("Remaining times export failed.\nIs the disk full?\n")); } + + // add remaining time lines where needed + _parser.parse_line(gcode_line, + [this, &g1_lines_count, &last_recorded_time, &in, &out, &path_tmp, time_mask, interval](GCodeReader& reader, const GCodeReader::GCodeLine& line) + { + if (line.cmd_is("G1")) + { + ++g1_lines_count; + for (const Block& block : _blocks) + { + if (block.g1_line_id == g1_lines_count) + { + if ((last_recorded_time == _time) || (last_recorded_time - block.time.remaining > interval)) + { + char buffer[1024]; + sprintf(buffer, time_mask.c_str(), std::to_string((int)(100.0f * block.time.elapsed / _time)).c_str(), _get_time_minutes(block.time.remaining).c_str()); + + fwrite((const void*)buffer, 1, ::strlen(buffer), out); + if (ferror(out)) + { + in.close(); + fclose(out); + boost::nowide::remove(path_tmp.c_str()); + throw std::runtime_error(std::string("Remaining times export failed.\nIs the disk full?\n")); + } + + last_recorded_time = block.time.remaining; + break; + } + } + } + } + }); } fclose(out); @@ -353,6 +486,7 @@ namespace Slic3r { return true; } +//################################################################################################################# void GCodeTimeEstimator::set_axis_position(EAxis axis, float position) { @@ -371,6 +505,25 @@ namespace Slic3r { void GCodeTimeEstimator::set_axis_max_jerk(EAxis axis, float jerk) { +//############################################################################################################3 + if ((axis == X) || (axis == Y)) + { + switch (_mode) + { + default: + case Normal: + { + jerk = std::min(jerk, NORMAL_AXIS_MAX_JERK[axis]); + break; + } + case Silent: + { + jerk = std::min(jerk, SILENT_AXIS_MAX_JERK[axis]); + break; + } + } + } +//############################################################################################################3 _state.axis[axis].max_jerk = jerk; } @@ -494,6 +647,33 @@ namespace Slic3r { return _state.e_local_positioning_type; } +//################################################################################################################# + bool GCodeTimeEstimator::are_remaining_times_enabled() const + { + return _state.remaining_times_enabled; + } + + void GCodeTimeEstimator::set_remaining_times_enabled(bool enable) + { + _state.remaining_times_enabled = enable; + } + + int GCodeTimeEstimator::get_g1_line_id() const + { + return _state.g1_line_id; + } + + void GCodeTimeEstimator::increment_g1_line_id() + { + ++_state.g1_line_id; + } + + void GCodeTimeEstimator::reset_g1_line_id() + { + _state.g1_line_id = 0; + } +//################################################################################################################# + void GCodeTimeEstimator::add_additional_time(float timeSec) { _state.additional_time += timeSec; @@ -515,13 +695,22 @@ namespace Slic3r { set_dialect(gcfRepRap); set_global_positioning_type(Absolute); set_e_local_positioning_type(Absolute); +//################################################################################################################# + set_remaining_times_enabled(false); +//################################################################################################################# switch (_mode) { default: - case Default: +//############################################################################################################3 + case Normal: +// case Default: +//############################################################################################################3 { - _set_default_as_default(); +//############################################################################################################3 + _set_default_as_normal(); +// _set_default_as_default(); +//############################################################################################################3 break; } case Silent: @@ -567,6 +756,10 @@ namespace Slic3r { set_axis_position(Z, 0.0f); set_additional_time(0.0f); + +//############################################################################################################3 + reset_g1_line_id(); +//############################################################################################################3 } void GCodeTimeEstimator::_reset_time() @@ -579,22 +772,61 @@ namespace Slic3r { _blocks.clear(); } - void GCodeTimeEstimator::_set_default_as_default() +//############################################################################################################3 + void GCodeTimeEstimator::_set_default_as_normal() +// void GCodeTimeEstimator::_set_default_as_default() +//############################################################################################################3 { - set_feedrate(DEFAULT_FEEDRATE); - set_acceleration(DEFAULT_ACCELERATION); - set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION); - set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE); - set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE); - set_extrude_factor_override_percentage(DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE); +//############################################################################################################3 + set_feedrate(NORMAL_FEEDRATE); + set_acceleration(NORMAL_ACCELERATION); + set_retract_acceleration(NORMAL_RETRACT_ACCELERATION); + set_minimum_feedrate(NORMAL_MINIMUM_FEEDRATE); + set_minimum_travel_feedrate(NORMAL_MINIMUM_TRAVEL_FEEDRATE); + set_extrude_factor_override_percentage(NORMAL_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE); for (unsigned char a = X; a < Num_Axis; ++a) { EAxis axis = (EAxis)a; - set_axis_max_feedrate(axis, DEFAULT_AXIS_MAX_FEEDRATE[a]); - set_axis_max_acceleration(axis, DEFAULT_AXIS_MAX_ACCELERATION[a]); - set_axis_max_jerk(axis, DEFAULT_AXIS_MAX_JERK[a]); + set_axis_max_feedrate(axis, NORMAL_AXIS_MAX_FEEDRATE[a]); + set_axis_max_acceleration(axis, NORMAL_AXIS_MAX_ACCELERATION[a]); + set_axis_max_jerk(axis, NORMAL_AXIS_MAX_JERK[a]); } + + std::cout << "Normal Default" << std::endl; + std::cout << "set_acceleration " << NORMAL_ACCELERATION << std::endl; + std::cout << "set_retract_acceleration " << NORMAL_RETRACT_ACCELERATION << std::endl; + std::cout << "set_minimum_feedrate " << NORMAL_MINIMUM_FEEDRATE << std::endl; + std::cout << "set_minimum_travel_feedrate " << NORMAL_MINIMUM_TRAVEL_FEEDRATE << std::endl; + std::cout << "set_axis_max_acceleration X " << NORMAL_AXIS_MAX_ACCELERATION[X] << std::endl; + std::cout << "set_axis_max_acceleration Y " << NORMAL_AXIS_MAX_ACCELERATION[Y] << std::endl; + std::cout << "set_axis_max_acceleration Z " << NORMAL_AXIS_MAX_ACCELERATION[Z] << std::endl; + std::cout << "set_axis_max_acceleration E " << NORMAL_AXIS_MAX_ACCELERATION[E] << std::endl; + std::cout << "set_axis_max_feedrate X " << NORMAL_AXIS_MAX_FEEDRATE[X] << std::endl; + std::cout << "set_axis_max_feedrate Y " << NORMAL_AXIS_MAX_FEEDRATE[Y] << std::endl; + std::cout << "set_axis_max_feedrate Z " << NORMAL_AXIS_MAX_FEEDRATE[Z] << std::endl; + std::cout << "set_axis_max_feedrate E " << NORMAL_AXIS_MAX_FEEDRATE[E] << std::endl; + std::cout << "set_axis_max_jerk X " << NORMAL_AXIS_MAX_JERK[X] << std::endl; + std::cout << "set_axis_max_jerk Y " << NORMAL_AXIS_MAX_JERK[Y] << std::endl; + std::cout << "set_axis_max_jerk Z " << NORMAL_AXIS_MAX_JERK[Z] << std::endl; + std::cout << "set_axis_max_jerk E " << NORMAL_AXIS_MAX_JERK[E] << std::endl; + + +// set_feedrate(DEFAULT_FEEDRATE); +// set_acceleration(DEFAULT_ACCELERATION); +// set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION); +// set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE); +// set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE); +// set_extrude_factor_override_percentage(DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE); +// +// for (unsigned char a = X; a < Num_Axis; ++a) +// { +// EAxis axis = (EAxis)a; +// set_axis_max_feedrate(axis, DEFAULT_AXIS_MAX_FEEDRATE[a]); +// set_axis_max_acceleration(axis, DEFAULT_AXIS_MAX_ACCELERATION[a]); +// set_axis_max_jerk(axis, DEFAULT_AXIS_MAX_JERK[a]); +// } +//############################################################################################################3 } void GCodeTimeEstimator::_set_default_as_silent() @@ -631,7 +863,10 @@ namespace Slic3r { _time += get_additional_time(); - for (const Block& block : _blocks) +//########################################################################################################################## + for (Block& block : _blocks) +// for (const Block& block : _blocks) +//########################################################################################################################## { if (block.st_synchronized) continue; @@ -642,6 +877,9 @@ namespace Slic3r { block_time += block.cruise_time(); block_time += block.deceleration_time(); _time += block_time; +//########################################################################################################################## + block.time.elapsed = _time; +//########################################################################################################################## MovesStatsMap::iterator it = _moves_stats.find(block.move_type); if (it == _moves_stats.end()) @@ -653,10 +891,23 @@ namespace Slic3r { _time += block.acceleration_time(); _time += block.cruise_time(); _time += block.deceleration_time(); +//########################################################################################################################## + block.time.elapsed = _time; +//########################################################################################################################## #endif // ENABLE_MOVE_STATS } } +//################################################################################################################# + void GCodeTimeEstimator::_calculate_remaining_times() + { + for (Block& block : _blocks) + { + block.calculate_remaining_time(_time); + } + } +//################################################################################################################# + void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) { PROFILE_FUNC(); @@ -790,6 +1041,10 @@ namespace Slic3r { void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) { +//############################################################################################################3 + increment_g1_line_id(); +//############################################################################################################3 + // updates axes positions from line EUnits units = get_units(); float new_pos[Num_Axis]; @@ -808,6 +1063,9 @@ namespace Slic3r { // fills block data Block block; +//############################################################################################################3 + block.g1_line_id = get_g1_line_id(); +//############################################################################################################3 // calculates block movement deltas float max_abs_delta = 0.0f; diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 14ff1efeac..924c9e3030 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -19,7 +19,10 @@ namespace Slic3r { public: enum EMode : unsigned char { - Default, +//####################################################################################################################################################################### + Normal, +// Default, +//####################################################################################################################################################################### Silent }; @@ -77,6 +80,10 @@ namespace Slic3r { float minimum_feedrate; // mm/s float minimum_travel_feedrate; // mm/s float extrude_factor_override_percentage; +//################################################################################################################# + bool remaining_times_enabled; + unsigned int g1_line_id; +//################################################################################################################# }; public: @@ -127,6 +134,15 @@ namespace Slic3r { bool nominal_length; }; +//################################################################################################################# + struct Time + { + float elapsed; + float remaining; + + Time(); + }; +//################################################################################################################# #if ENABLE_MOVE_STATS EMoveType move_type; @@ -140,6 +156,10 @@ namespace Slic3r { FeedrateProfile feedrate; Trapezoid trapezoid; +//################################################################################################################# + Time time; + unsigned int g1_line_id; +//################################################################################################################# bool st_synchronized; @@ -169,6 +189,10 @@ namespace Slic3r { // Calculates this block's trapezoid void calculate_trapezoid(); +//################################################################################################################# + void calculate_remaining_time(float final_time); +//################################################################################################################# + // Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the // acceleration within the allotted distance. static float max_allowable_speed(float acceleration, float target_velocity, float distance); @@ -231,12 +255,25 @@ namespace Slic3r { // Calculates the time estimate from the gcode contained in given list of gcode lines void calculate_time_from_lines(const std::vector& gcode_lines); - // Calculates the time estimate from the gcode lines added using add_gcode_line() or add_gcode_block() - // and returns it in a formatted string - std::string get_elapsed_time_string(); +//############################################################################################################3 +// // Calculates the time estimate from the gcode lines added using add_gcode_line() or add_gcode_block() +// // and returns it in a formatted string +// std::string get_elapsed_time_string(); +//############################################################################################################3 - // Converts elapsed time lines, contained in the gcode saved with the given filename, into remaining time commands - static bool post_process_elapsed_times(const std::string& filename, float default_time, float silent_time); +//############################################################################################################3 +// // Converts elapsed time lines, contained in the gcode saved with the given filename, into remaining time commands +// static bool post_process_elapsed_times(const std::string& filename, float default_time, float silent_time); +//############################################################################################################3 + +//################################################################################################################# + // Process the gcode contained in the file with the given filename, + // placing in it new lines (M73) containing the remaining time, at the given interval in seconds + // and saving the result back in the same file + // This time estimator should have been already used to calculate the time estimate for the gcode + // contained in the given file before to call this method + bool post_process_remaining_times(const std::string& filename, float interval_sec); +//################################################################################################################# // Set current position on the given axis with the given value void set_axis_position(EAxis axis, float position); @@ -282,6 +319,15 @@ namespace Slic3r { void set_e_local_positioning_type(EPositioningType type); EPositioningType get_e_local_positioning_type() const; +//################################################################################################################# + bool are_remaining_times_enabled() const; + void set_remaining_times_enabled(bool enable); + + int get_g1_line_id() const; + void increment_g1_line_id(); + void reset_g1_line_id(); +//################################################################################################################# + void add_additional_time(float timeSec); void set_additional_time(float timeSec); float get_additional_time() const; @@ -305,7 +351,10 @@ namespace Slic3r { void _reset_time(); void _reset_blocks(); - void _set_default_as_default(); +//############################################################################################################3 + void _set_default_as_normal(); +// void _set_default_as_default(); +//############################################################################################################3 void _set_default_as_silent(); void _set_blocks_st_synchronize(bool state); @@ -313,6 +362,10 @@ namespace Slic3r { // Calculates the time estimate void _calculate_time(); +//################################################################################################################# + void _calculate_remaining_times(); +//################################################################################################################# + // Processes the given gcode line void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line); diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index db92087b77..9fd59d690e 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -235,7 +235,10 @@ public: PrintRegionPtrs regions; PlaceholderParser placeholder_parser; // TODO: status_cb - std::string estimated_default_print_time; +//####################################################################################################################################################################### + std::string estimated_normal_print_time; +// std::string estimated_default_print_time; +//####################################################################################################################################################################### std::string estimated_silent_print_time; double total_used_filament, total_extruded_volume, total_cost, total_weight; std::map filament_stats; diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 8c66d44ec8..49568e0ab2 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -936,7 +936,10 @@ PrintConfigDef::PrintConfigDef() def->sidetext = L("mm/s²"); def->min = 0; def->width = machine_limits_opt_width; - def->default_value = new ConfigOptionFloats(1500., 1250.); +//################################################################################################################################## + def->default_value = new ConfigOptionFloats{ 1500., 1250. }; +// def->default_value = new ConfigOptionFloats(1500., 1250.); +//################################################################################################################################## // M204 T... [mm/sec^2] def = this->add("machine_max_acceleration_retracting", coFloats); @@ -946,7 +949,10 @@ PrintConfigDef::PrintConfigDef() def->sidetext = L("mm/s²"); def->min = 0; def->width = machine_limits_opt_width; - def->default_value = new ConfigOptionFloats(1500., 1250.); +//################################################################################################################################## + def->default_value = new ConfigOptionFloats{ 1500., 1250. }; +// def->default_value = new ConfigOptionFloats(1500., 1250.); +//################################################################################################################################## def = this->add("max_fan_speed", coInts); def->label = L("Max"); diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index bc5eb74335..7170649166 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -145,8 +145,8 @@ _constant() %code%{ RETVAL = &THIS->skirt; %}; Ref brim() %code%{ RETVAL = &THIS->brim; %}; - std::string estimated_default_print_time() - %code%{ RETVAL = THIS->estimated_default_print_time; %}; + std::string estimated_normal_print_time() + %code%{ RETVAL = THIS->estimated_normal_print_time; %}; std::string estimated_silent_print_time() %code%{ RETVAL = THIS->estimated_silent_print_time; %}; From 9725966f38d10f65bbec5413fb0e8e323418c072 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 28 Jun 2018 08:52:07 +0200 Subject: [PATCH 14/26] Time estimate uses G1 lines containing E parameter for remaining time calculations --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 44 +++++-------------------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 20 +---------- 2 files changed, 9 insertions(+), 55 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 8f306835fd..916a93eba9 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -106,14 +106,6 @@ namespace Slic3r { return ::sqrt(value); } -//################################################################################################################# - GCodeTimeEstimator::Block::Time::Time() - : elapsed(-1.0f) - , remaining(-1.0f) - { - } -//################################################################################################################# - GCodeTimeEstimator::Block::Block() : st_synchronized(false) //################################################################################################################# @@ -183,13 +175,6 @@ namespace Slic3r { trapezoid.decelerate_after = accelerate_distance + cruise_distance; } -//################################################################################################################# - void GCodeTimeEstimator::Block::calculate_remaining_time(float final_time) - { - time.remaining = (time.elapsed >= 0.0f) ? final_time - time.elapsed : -1.0f; - } -//################################################################################################################# - float GCodeTimeEstimator::Block::max_allowable_speed(float acceleration, float target_velocity, float distance) { // to avoid invalid negative numbers due to numerical imprecision @@ -248,10 +233,6 @@ namespace Slic3r { _reset_time(); _set_blocks_st_synchronize(false); _calculate_time(); -//################################################################################################################# - if (are_remaining_times_enabled()) - _calculate_remaining_times(); -//################################################################################################################# #if ENABLE_MOVE_STATS _log_moves_stats(); @@ -446,17 +427,18 @@ namespace Slic3r { _parser.parse_line(gcode_line, [this, &g1_lines_count, &last_recorded_time, &in, &out, &path_tmp, time_mask, interval](GCodeReader& reader, const GCodeReader::GCodeLine& line) { - if (line.cmd_is("G1")) + if (line.cmd_is("G1") && line.has_e()) { ++g1_lines_count; for (const Block& block : _blocks) { - if (block.g1_line_id == g1_lines_count) + if ((block.g1_line_id == g1_lines_count) && (block.elapsed_time != -1.0f)) { - if ((last_recorded_time == _time) || (last_recorded_time - block.time.remaining > interval)) + float block_remaining_time = _time - block.elapsed_time; + if ((last_recorded_time == _time) || (last_recorded_time - block_remaining_time > interval)) { char buffer[1024]; - sprintf(buffer, time_mask.c_str(), std::to_string((int)(100.0f * block.time.elapsed / _time)).c_str(), _get_time_minutes(block.time.remaining).c_str()); + sprintf(buffer, time_mask.c_str(), std::to_string((int)(100.0f * block.elapsed_time / _time)).c_str(), _get_time_minutes(block_remaining_time).c_str()); fwrite((const void*)buffer, 1, ::strlen(buffer), out); if (ferror(out)) @@ -467,7 +449,7 @@ namespace Slic3r { throw std::runtime_error(std::string("Remaining times export failed.\nIs the disk full?\n")); } - last_recorded_time = block.time.remaining; + last_recorded_time = block_remaining_time; break; } } @@ -878,7 +860,7 @@ namespace Slic3r { block_time += block.deceleration_time(); _time += block_time; //########################################################################################################################## - block.time.elapsed = _time; + block.elapsed_time = are_remaining_times_enabled() ? _time : -1.0f; //########################################################################################################################## MovesStatsMap::iterator it = _moves_stats.find(block.move_type); @@ -892,22 +874,12 @@ namespace Slic3r { _time += block.cruise_time(); _time += block.deceleration_time(); //########################################################################################################################## - block.time.elapsed = _time; + block.elapsed_time = are_remaining_times_enabled() ? _time : -1.0f; //########################################################################################################################## #endif // ENABLE_MOVE_STATS } } -//################################################################################################################# - void GCodeTimeEstimator::_calculate_remaining_times() - { - for (Block& block : _blocks) - { - block.calculate_remaining_time(_time); - } - } -//################################################################################################################# - void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) { PROFILE_FUNC(); diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 924c9e3030..cbb43fbeaa 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -134,16 +134,6 @@ namespace Slic3r { bool nominal_length; }; -//################################################################################################################# - struct Time - { - float elapsed; - float remaining; - - Time(); - }; -//################################################################################################################# - #if ENABLE_MOVE_STATS EMoveType move_type; #endif // ENABLE_MOVE_STATS @@ -157,7 +147,7 @@ namespace Slic3r { FeedrateProfile feedrate; Trapezoid trapezoid; //################################################################################################################# - Time time; + float elapsed_time; unsigned int g1_line_id; //################################################################################################################# @@ -189,10 +179,6 @@ namespace Slic3r { // Calculates this block's trapezoid void calculate_trapezoid(); -//################################################################################################################# - void calculate_remaining_time(float final_time); -//################################################################################################################# - // Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the // acceleration within the allotted distance. static float max_allowable_speed(float acceleration, float target_velocity, float distance); @@ -362,10 +348,6 @@ namespace Slic3r { // Calculates the time estimate void _calculate_time(); -//################################################################################################################# - void _calculate_remaining_times(); -//################################################################################################################# - // Processes the given gcode line void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line); From 7d61b2076f4a003104f9a45ba7b130cd97b15eb5 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 28 Jun 2018 09:24:07 +0200 Subject: [PATCH 15/26] Faster remaining time calculation --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 916a93eba9..fc43748a94 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -402,7 +402,8 @@ namespace Slic3r { } unsigned int g1_lines_count = 0; - float last_recorded_time = _time; + float last_recorded_time = 0.0f; + int last_recorded_id = -1; std::string gcode_line; while (std::getline(in, gcode_line)) { @@ -425,17 +426,21 @@ namespace Slic3r { // add remaining time lines where needed _parser.parse_line(gcode_line, - [this, &g1_lines_count, &last_recorded_time, &in, &out, &path_tmp, time_mask, interval](GCodeReader& reader, const GCodeReader::GCodeLine& line) + [this, &g1_lines_count, &last_recorded_time, &last_recorded_id, &in, &out, &path_tmp, time_mask, interval](GCodeReader& reader, const GCodeReader::GCodeLine& line) { - if (line.cmd_is("G1") && line.has_e()) + if (line.cmd_is("G1")) { ++g1_lines_count; - for (const Block& block : _blocks) + if (!line.has_e()) + return; + + for (int i = last_recorded_id + 1; i < (int)_blocks.size(); ++i) { + const Block& block = _blocks[i]; if ((block.g1_line_id == g1_lines_count) && (block.elapsed_time != -1.0f)) { float block_remaining_time = _time - block.elapsed_time; - if ((last_recorded_time == _time) || (last_recorded_time - block_remaining_time > interval)) + if (std::abs(last_recorded_time - block_remaining_time) > interval) { char buffer[1024]; sprintf(buffer, time_mask.c_str(), std::to_string((int)(100.0f * block.elapsed_time / _time)).c_str(), _get_time_minutes(block_remaining_time).c_str()); @@ -450,7 +455,8 @@ namespace Slic3r { } last_recorded_time = block_remaining_time; - break; + last_recorded_id = i; + return; } } } From 5605835ba9d4a48099401351843143f6088b72d2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 28 Jun 2018 12:40:27 +0200 Subject: [PATCH 16/26] Use silent_mode only with MK3 printer --- xs/src/slic3r/GUI/Tab.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index cf1b84639b..21fde64f2d 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1921,8 +1921,12 @@ void TabPrinter::update(){ get_field("single_extruder_multi_material")->toggle(have_multiple_extruders); bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; - get_field("silent_mode")->toggle(is_marlin_flavor); - if (m_use_silent_mode != m_config->opt_bool("silent_mode")) { + + const std::string &printer_model = m_config->opt_string("printer_model"); + bool can_use_silent_mode = printer_model.empty() ? false : printer_model == "MK3"; // "true" only for MK3 printers + + get_field("silent_mode")->toggle(can_use_silent_mode && is_marlin_flavor); + if (can_use_silent_mode && m_use_silent_mode != m_config->opt_bool("silent_mode")) { m_rebuild_kinematics_page = true; m_use_silent_mode = m_config->opt_bool("silent_mode"); } From dc25df7b3225665b1e857abb977bfdfce440c143 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 28 Jun 2018 13:57:28 +0200 Subject: [PATCH 17/26] Faster remaining times export --- xs/src/libslic3r/GCode.cpp | 39 +++---- xs/src/libslic3r/GCodeTimeEstimator.cpp | 138 +++++++++++++----------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 5 +- 3 files changed, 98 insertions(+), 84 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 1f0aac816a..9f3818104e 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -436,23 +436,23 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config.machine_max_jerk_z.values[0]); m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config.machine_max_jerk_e.values[0]); - std::cout << "Normal" << std::endl; - std::cout << "set_acceleration " << print.config.machine_max_acceleration_extruding.values[0] << std::endl; - std::cout << "set_retract_acceleration " << print.config.machine_max_acceleration_retracting.values[0] << std::endl; - std::cout << "set_minimum_feedrate " << print.config.machine_min_extruding_rate.values[0] << std::endl; - std::cout << "set_minimum_travel_feedrate " << print.config.machine_min_travel_rate.values[0] << std::endl; - std::cout << "set_axis_max_acceleration X " << print.config.machine_max_acceleration_x.values[0] << std::endl; - std::cout << "set_axis_max_acceleration Y " << print.config.machine_max_acceleration_y.values[0] << std::endl; - std::cout << "set_axis_max_acceleration Z " << print.config.machine_max_acceleration_z.values[0] << std::endl; - std::cout << "set_axis_max_acceleration E " << print.config.machine_max_acceleration_e.values[0] << std::endl; - std::cout << "set_axis_max_feedrate X " << print.config.machine_max_feedrate_x.values[0] << std::endl; - std::cout << "set_axis_max_feedrate Y " << print.config.machine_max_feedrate_y.values[0] << std::endl; - std::cout << "set_axis_max_feedrate Z " << print.config.machine_max_feedrate_z.values[0] << std::endl; - std::cout << "set_axis_max_feedrate E " << print.config.machine_max_feedrate_e.values[0] << std::endl; - std::cout << "set_axis_max_jerk X " << print.config.machine_max_jerk_x.values[0] << std::endl; - std::cout << "set_axis_max_jerk Y " << print.config.machine_max_jerk_y.values[0] << std::endl; - std::cout << "set_axis_max_jerk Z " << print.config.machine_max_jerk_z.values[0] << std::endl; - std::cout << "set_axis_max_jerk E " << print.config.machine_max_jerk_e.values[0] << std::endl; +// std::cout << "Normal" << std::endl; +// std::cout << "set_acceleration " << print.config.machine_max_acceleration_extruding.values[0] << std::endl; +// std::cout << "set_retract_acceleration " << print.config.machine_max_acceleration_retracting.values[0] << std::endl; +// std::cout << "set_minimum_feedrate " << print.config.machine_min_extruding_rate.values[0] << std::endl; +// std::cout << "set_minimum_travel_feedrate " << print.config.machine_min_travel_rate.values[0] << std::endl; +// std::cout << "set_axis_max_acceleration X " << print.config.machine_max_acceleration_x.values[0] << std::endl; +// std::cout << "set_axis_max_acceleration Y " << print.config.machine_max_acceleration_y.values[0] << std::endl; +// std::cout << "set_axis_max_acceleration Z " << print.config.machine_max_acceleration_z.values[0] << std::endl; +// std::cout << "set_axis_max_acceleration E " << print.config.machine_max_acceleration_e.values[0] << std::endl; +// std::cout << "set_axis_max_feedrate X " << print.config.machine_max_feedrate_x.values[0] << std::endl; +// std::cout << "set_axis_max_feedrate Y " << print.config.machine_max_feedrate_y.values[0] << std::endl; +// std::cout << "set_axis_max_feedrate Z " << print.config.machine_max_feedrate_z.values[0] << std::endl; +// std::cout << "set_axis_max_feedrate E " << print.config.machine_max_feedrate_e.values[0] << std::endl; +// std::cout << "set_axis_max_jerk X " << print.config.machine_max_jerk_x.values[0] << std::endl; +// std::cout << "set_axis_max_jerk Y " << print.config.machine_max_jerk_y.values[0] << std::endl; +// std::cout << "set_axis_max_jerk Z " << print.config.machine_max_jerk_z.values[0] << std::endl; +// std::cout << "set_axis_max_jerk E " << print.config.machine_max_jerk_e.values[0] << std::endl; // m_default_time_estimator.reset(); @@ -945,7 +945,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) double extruded_volume = extruder.extruded_volume(); double filament_weight = extruded_volume * extruder.filament_density() * 0.001; double filament_cost = filament_weight * extruder.filament_cost() * 0.001; - print.filament_stats.insert(std::pair(extruder.id(), used_filament)); +//####################################################################################################################################################################### + print.filament_stats.insert(std::pair(extruder.id(), (float)used_filament)); +// print.filament_stats.insert(std::pair(extruder.id(), used_filament)); +//####################################################################################################################################################################### _write_format(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001); if (filament_weight > 0.) { print.total_weight = print.total_weight + filament_weight; diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index fc43748a94..15a346399a 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -108,9 +108,6 @@ namespace Slic3r { GCodeTimeEstimator::Block::Block() : st_synchronized(false) -//################################################################################################################# - , g1_line_id(0) -//################################################################################################################# { } @@ -403,8 +400,10 @@ namespace Slic3r { unsigned int g1_lines_count = 0; float last_recorded_time = 0.0f; - int last_recorded_id = -1; std::string gcode_line; + // buffer line to export only when greater than 64K to reduce writing calls + std::string export_line; + char time_line[64]; while (std::getline(in, gcode_line)) { if (!in.good()) @@ -413,9 +412,56 @@ namespace Slic3r { throw std::runtime_error(std::string("Remaining times export failed.\nError while reading from file.\n")); } - // saves back the line gcode_line += "\n"; - fwrite((const void*)gcode_line.c_str(), 1, gcode_line.length(), out); + + // add remaining time lines where needed + _parser.parse_line(gcode_line, + [this, &g1_lines_count, &last_recorded_time, &time_line, &gcode_line, time_mask, interval](GCodeReader& reader, const GCodeReader::GCodeLine& line) + { + if (line.cmd_is("G1")) + { + ++g1_lines_count; + + if (!line.has_e()) + return; + + G1LineIdToBlockIdMap::const_iterator it = _g1_line_ids.find(g1_lines_count); + if ((it != _g1_line_ids.end()) && (it->second < (unsigned int)_blocks.size())) + { + const Block& block = _blocks[it->second]; + if (block.elapsed_time != -1.0f) + { + float block_remaining_time = _time - block.elapsed_time; + if (std::abs(last_recorded_time - block_remaining_time) > interval) + { + sprintf(time_line, time_mask.c_str(), std::to_string((int)(100.0f * block.elapsed_time / _time)).c_str(), _get_time_minutes(block_remaining_time).c_str()); + gcode_line += time_line; + + last_recorded_time = block_remaining_time; + } + } + } + } + }); + + export_line += gcode_line; + if (export_line.length() > 65535) + { + fwrite((const void*)export_line.c_str(), 1, export_line.length(), out); + if (ferror(out)) + { + in.close(); + fclose(out); + boost::nowide::remove(path_tmp.c_str()); + throw std::runtime_error(std::string("Remaining times export failed.\nIs the disk full?\n")); + } + export_line.clear(); + } + } + + if (export_line.length() > 0) + { + fwrite((const void*)export_line.c_str(), 1, export_line.length(), out); if (ferror(out)) { in.close(); @@ -423,45 +469,6 @@ namespace Slic3r { boost::nowide::remove(path_tmp.c_str()); throw std::runtime_error(std::string("Remaining times export failed.\nIs the disk full?\n")); } - - // add remaining time lines where needed - _parser.parse_line(gcode_line, - [this, &g1_lines_count, &last_recorded_time, &last_recorded_id, &in, &out, &path_tmp, time_mask, interval](GCodeReader& reader, const GCodeReader::GCodeLine& line) - { - if (line.cmd_is("G1")) - { - ++g1_lines_count; - if (!line.has_e()) - return; - - for (int i = last_recorded_id + 1; i < (int)_blocks.size(); ++i) - { - const Block& block = _blocks[i]; - if ((block.g1_line_id == g1_lines_count) && (block.elapsed_time != -1.0f)) - { - float block_remaining_time = _time - block.elapsed_time; - if (std::abs(last_recorded_time - block_remaining_time) > interval) - { - char buffer[1024]; - sprintf(buffer, time_mask.c_str(), std::to_string((int)(100.0f * block.elapsed_time / _time)).c_str(), _get_time_minutes(block_remaining_time).c_str()); - - fwrite((const void*)buffer, 1, ::strlen(buffer), out); - if (ferror(out)) - { - in.close(); - fclose(out); - boost::nowide::remove(path_tmp.c_str()); - throw std::runtime_error(std::string("Remaining times export failed.\nIs the disk full?\n")); - } - - last_recorded_time = block_remaining_time; - last_recorded_id = i; - return; - } - } - } - } - }); } fclose(out); @@ -747,6 +754,7 @@ namespace Slic3r { //############################################################################################################3 reset_g1_line_id(); + _g1_line_ids.clear(); //############################################################################################################3 } @@ -781,23 +789,23 @@ namespace Slic3r { set_axis_max_jerk(axis, NORMAL_AXIS_MAX_JERK[a]); } - std::cout << "Normal Default" << std::endl; - std::cout << "set_acceleration " << NORMAL_ACCELERATION << std::endl; - std::cout << "set_retract_acceleration " << NORMAL_RETRACT_ACCELERATION << std::endl; - std::cout << "set_minimum_feedrate " << NORMAL_MINIMUM_FEEDRATE << std::endl; - std::cout << "set_minimum_travel_feedrate " << NORMAL_MINIMUM_TRAVEL_FEEDRATE << std::endl; - std::cout << "set_axis_max_acceleration X " << NORMAL_AXIS_MAX_ACCELERATION[X] << std::endl; - std::cout << "set_axis_max_acceleration Y " << NORMAL_AXIS_MAX_ACCELERATION[Y] << std::endl; - std::cout << "set_axis_max_acceleration Z " << NORMAL_AXIS_MAX_ACCELERATION[Z] << std::endl; - std::cout << "set_axis_max_acceleration E " << NORMAL_AXIS_MAX_ACCELERATION[E] << std::endl; - std::cout << "set_axis_max_feedrate X " << NORMAL_AXIS_MAX_FEEDRATE[X] << std::endl; - std::cout << "set_axis_max_feedrate Y " << NORMAL_AXIS_MAX_FEEDRATE[Y] << std::endl; - std::cout << "set_axis_max_feedrate Z " << NORMAL_AXIS_MAX_FEEDRATE[Z] << std::endl; - std::cout << "set_axis_max_feedrate E " << NORMAL_AXIS_MAX_FEEDRATE[E] << std::endl; - std::cout << "set_axis_max_jerk X " << NORMAL_AXIS_MAX_JERK[X] << std::endl; - std::cout << "set_axis_max_jerk Y " << NORMAL_AXIS_MAX_JERK[Y] << std::endl; - std::cout << "set_axis_max_jerk Z " << NORMAL_AXIS_MAX_JERK[Z] << std::endl; - std::cout << "set_axis_max_jerk E " << NORMAL_AXIS_MAX_JERK[E] << std::endl; +// std::cout << "Normal Default" << std::endl; +// std::cout << "set_acceleration " << NORMAL_ACCELERATION << std::endl; +// std::cout << "set_retract_acceleration " << NORMAL_RETRACT_ACCELERATION << std::endl; +// std::cout << "set_minimum_feedrate " << NORMAL_MINIMUM_FEEDRATE << std::endl; +// std::cout << "set_minimum_travel_feedrate " << NORMAL_MINIMUM_TRAVEL_FEEDRATE << std::endl; +// std::cout << "set_axis_max_acceleration X " << NORMAL_AXIS_MAX_ACCELERATION[X] << std::endl; +// std::cout << "set_axis_max_acceleration Y " << NORMAL_AXIS_MAX_ACCELERATION[Y] << std::endl; +// std::cout << "set_axis_max_acceleration Z " << NORMAL_AXIS_MAX_ACCELERATION[Z] << std::endl; +// std::cout << "set_axis_max_acceleration E " << NORMAL_AXIS_MAX_ACCELERATION[E] << std::endl; +// std::cout << "set_axis_max_feedrate X " << NORMAL_AXIS_MAX_FEEDRATE[X] << std::endl; +// std::cout << "set_axis_max_feedrate Y " << NORMAL_AXIS_MAX_FEEDRATE[Y] << std::endl; +// std::cout << "set_axis_max_feedrate Z " << NORMAL_AXIS_MAX_FEEDRATE[Z] << std::endl; +// std::cout << "set_axis_max_feedrate E " << NORMAL_AXIS_MAX_FEEDRATE[E] << std::endl; +// std::cout << "set_axis_max_jerk X " << NORMAL_AXIS_MAX_JERK[X] << std::endl; +// std::cout << "set_axis_max_jerk Y " << NORMAL_AXIS_MAX_JERK[Y] << std::endl; +// std::cout << "set_axis_max_jerk Z " << NORMAL_AXIS_MAX_JERK[Z] << std::endl; +// std::cout << "set_axis_max_jerk E " << NORMAL_AXIS_MAX_JERK[E] << std::endl; // set_feedrate(DEFAULT_FEEDRATE); @@ -1041,9 +1049,6 @@ namespace Slic3r { // fills block data Block block; -//############################################################################################################3 - block.g1_line_id = get_g1_line_id(); -//############################################################################################################3 // calculates block movement deltas float max_abs_delta = 0.0f; @@ -1213,6 +1218,9 @@ namespace Slic3r { // adds block to blocks list _blocks.emplace_back(block); +//############################################################################################################3 + _g1_line_ids.insert(G1LineIdToBlockIdMap::value_type(get_g1_line_id(), (unsigned int)_blocks.size() - 1)); +//############################################################################################################3 } void GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index cbb43fbeaa..ef074f0738 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -148,7 +148,6 @@ namespace Slic3r { Trapezoid trapezoid; //################################################################################################################# float elapsed_time; - unsigned int g1_line_id; //################################################################################################################# bool st_synchronized; @@ -207,6 +206,8 @@ namespace Slic3r { typedef std::map MovesStatsMap; #endif // ENABLE_MOVE_STATS + typedef std::map G1LineIdToBlockIdMap; + private: EMode _mode; GCodeReader _parser; @@ -214,6 +215,8 @@ namespace Slic3r { Feedrates _curr; Feedrates _prev; BlocksList _blocks; + // Map between g1 line id and blocks id, used to speed up export of remaining times + G1LineIdToBlockIdMap _g1_line_ids; float _time; // s #if ENABLE_MOVE_STATS From cf1ccacd41e45b93319e7c2f4aaa05990a330865 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 13 Jul 2018 10:46:30 +0200 Subject: [PATCH 18/26] Perimeters test modified to skip lines M73 --- t/perimeters.t | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/t/perimeters.t b/t/perimeters.t index ee332616d1..d0657cb23f 100644 --- a/t/perimeters.t +++ b/t/perimeters.t @@ -175,7 +175,7 @@ use Slic3r::Test; if ($info->{extruding} && $info->{dist_XY} > 0) { $cur_loop ||= [ [$self->X, $self->Y] ]; push @$cur_loop, [ @$info{qw(new_X new_Y)} ]; - } else { + } elsif ($cmd ne 'M73') { # skips remaining time lines (M73) if ($cur_loop) { $has_cw_loops = 1 if Slic3r::Polygon->new(@$cur_loop)->is_clockwise; $cur_loop = undef; @@ -201,7 +201,7 @@ use Slic3r::Test; if ($info->{extruding} && $info->{dist_XY} > 0) { $cur_loop ||= [ [$self->X, $self->Y] ]; push @$cur_loop, [ @$info{qw(new_X new_Y)} ]; - } else { + } elsif ($cmd ne 'M73') { # skips remaining time lines (M73) if ($cur_loop) { $has_cw_loops = 1 if Slic3r::Polygon->new_scale(@$cur_loop)->is_clockwise; if ($self->F == $config->external_perimeter_speed*60) { @@ -306,7 +306,7 @@ use Slic3r::Test; if ($info->{extruding} && $info->{dist_XY} > 0 && ($args->{F} // $self->F) == $config->perimeter_speed*60) { $perimeters{$self->Z}++ if !$in_loop; $in_loop = 1; - } else { + } elsif ($cmd ne 'M73') { # skips remaining time lines (M73) $in_loop = 0; } }); @@ -430,7 +430,7 @@ use Slic3r::Test; push @seam_points, Slic3r::Point->new_scale($self->X, $self->Y); } $was_extruding = 1; - } else { + } elsif ($cmd ne 'M73') { # skips remaining time lines (M73) $was_extruding = 0; } }); From 75cf4e0947f8dc0a79ccea16f836d82d0022cf21 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 13 Jul 2018 11:32:50 +0200 Subject: [PATCH 19/26] Generate M73 lines for silent mode only for MK3 printers --- xs/src/libslic3r/GCode.cpp | 98 +----------- xs/src/libslic3r/GCode.hpp | 6 - xs/src/libslic3r/GCodeTimeEstimator.cpp | 191 +----------------------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 31 +--- xs/src/libslic3r/Print.hpp | 3 - xs/src/libslic3r/PrintConfig.cpp | 6 - xs/src/libslic3r/PrintConfig.hpp | 2 + 7 files changed, 7 insertions(+), 330 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 9f3818104e..434b76f6dd 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -375,15 +375,10 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ } fclose(file); -//################################################################################################################# m_normal_time_estimator.post_process_remaining_times(path_tmp, 60.0f); -//################################################################################################################# if (m_silent_time_estimator_enabled) -//############################################################################################################3 m_silent_time_estimator.post_process_remaining_times(path_tmp, 60.0f); -// GCodeTimeEstimator::post_process_elapsed_times(path_tmp, m_default_time_estimator.get_time(), m_silent_time_estimator.get_time()); -//############################################################################################################3 if (! this->m_placeholder_parser_failed_templates.empty()) { // G-code export proceeded, but some of the PlaceholderParser substitutions failed. @@ -415,10 +410,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) PROFILE_FUNC(); // resets time estimators -//####################################################################################################################################################################### m_normal_time_estimator.reset(); m_normal_time_estimator.set_dialect(print.config.gcode_flavor); - m_normal_time_estimator.set_remaining_times_enabled(false); m_normal_time_estimator.set_acceleration(print.config.machine_max_acceleration_extruding.values[0]); m_normal_time_estimator.set_retract_acceleration(print.config.machine_max_acceleration_retracting.values[0]); m_normal_time_estimator.set_minimum_feedrate(print.config.machine_min_extruding_rate.values[0]); @@ -436,51 +429,11 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config.machine_max_jerk_z.values[0]); m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config.machine_max_jerk_e.values[0]); -// std::cout << "Normal" << std::endl; -// std::cout << "set_acceleration " << print.config.machine_max_acceleration_extruding.values[0] << std::endl; -// std::cout << "set_retract_acceleration " << print.config.machine_max_acceleration_retracting.values[0] << std::endl; -// std::cout << "set_minimum_feedrate " << print.config.machine_min_extruding_rate.values[0] << std::endl; -// std::cout << "set_minimum_travel_feedrate " << print.config.machine_min_travel_rate.values[0] << std::endl; -// std::cout << "set_axis_max_acceleration X " << print.config.machine_max_acceleration_x.values[0] << std::endl; -// std::cout << "set_axis_max_acceleration Y " << print.config.machine_max_acceleration_y.values[0] << std::endl; -// std::cout << "set_axis_max_acceleration Z " << print.config.machine_max_acceleration_z.values[0] << std::endl; -// std::cout << "set_axis_max_acceleration E " << print.config.machine_max_acceleration_e.values[0] << std::endl; -// std::cout << "set_axis_max_feedrate X " << print.config.machine_max_feedrate_x.values[0] << std::endl; -// std::cout << "set_axis_max_feedrate Y " << print.config.machine_max_feedrate_y.values[0] << std::endl; -// std::cout << "set_axis_max_feedrate Z " << print.config.machine_max_feedrate_z.values[0] << std::endl; -// std::cout << "set_axis_max_feedrate E " << print.config.machine_max_feedrate_e.values[0] << std::endl; -// std::cout << "set_axis_max_jerk X " << print.config.machine_max_jerk_x.values[0] << std::endl; -// std::cout << "set_axis_max_jerk Y " << print.config.machine_max_jerk_y.values[0] << std::endl; -// std::cout << "set_axis_max_jerk Z " << print.config.machine_max_jerk_z.values[0] << std::endl; -// std::cout << "set_axis_max_jerk E " << print.config.machine_max_jerk_e.values[0] << std::endl; - - -// m_default_time_estimator.reset(); -// m_default_time_estimator.set_dialect(print.config.gcode_flavor); -// m_default_time_estimator.set_acceleration(print.config.machine_max_acceleration_extruding.values[0]); -// m_default_time_estimator.set_retract_acceleration(print.config.machine_max_acceleration_retracting.values[0]); -// m_default_time_estimator.set_minimum_feedrate(print.config.machine_min_extruding_rate.values[0]); -// m_default_time_estimator.set_minimum_travel_feedrate(print.config.machine_min_travel_rate.values[0]); -// m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config.machine_max_acceleration_x.values[0]); -// m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config.machine_max_acceleration_y.values[0]); -// m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config.machine_max_acceleration_z.values[0]); -// m_default_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config.machine_max_acceleration_e.values[0]); -// m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config.machine_max_feedrate_x.values[0]); -// m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config.machine_max_feedrate_y.values[0]); -// m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config.machine_max_feedrate_z.values[0]); -// m_default_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config.machine_max_feedrate_e.values[0]); -// m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config.machine_max_jerk_x.values[0]); -// m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config.machine_max_jerk_y.values[0]); -// m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config.machine_max_jerk_z.values[0]); -// m_default_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config.machine_max_jerk_e.values[0]); -//####################################################################################################################################################################### - - m_silent_time_estimator_enabled = (print.config.gcode_flavor == gcfMarlin) && print.config.silent_mode; + m_silent_time_estimator_enabled = (print.config.gcode_flavor == gcfMarlin) && print.config.silent_mode && boost::starts_with(print.config.printer_model.value, "MK3"); if (m_silent_time_estimator_enabled) { m_silent_time_estimator.reset(); m_silent_time_estimator.set_dialect(print.config.gcode_flavor); - m_silent_time_estimator.set_remaining_times_enabled(false); m_silent_time_estimator.set_acceleration(print.config.machine_max_acceleration_extruding.values[1]); m_silent_time_estimator.set_retract_acceleration(print.config.machine_max_acceleration_retracting.values[1]); m_silent_time_estimator.set_minimum_feedrate(print.config.machine_min_extruding_rate.values[1]); @@ -687,15 +640,6 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) _writeln(file, buf); } -//####################################################################################################################################################################### -// // before start gcode time estimation -// if (m_silent_time_estimator_enabled) -// { -// _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); -// _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); -// } -//####################################################################################################################################################################### - // Write the custom start G-code _writeln(file, start_gcode); // Process filament-specific gcode in extruder order. @@ -900,34 +844,15 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) for (const std::string &end_gcode : print.config.end_filament_gcode.values) _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()), &config)); } -//####################################################################################################################################################################### -// // before end gcode time estimation -// if (m_silent_time_estimator_enabled) -// { -// _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); -// _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); -// } -//####################################################################################################################################################################### _writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id(), &config)); } _write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% _write(file, m_writer.postamble()); // calculates estimated printing time -//####################################################################################################################################################################### - m_normal_time_estimator.set_remaining_times_enabled(true); m_normal_time_estimator.calculate_time(); -// m_default_time_estimator.calculate_time(); -//####################################################################################################################################################################### if (m_silent_time_estimator_enabled) -//####################################################################################################################################################################### - { - m_silent_time_estimator.set_remaining_times_enabled(true); -//####################################################################################################################################################################### m_silent_time_estimator.calculate_time(); -//####################################################################################################################################################################### - } -//####################################################################################################################################################################### // Get filament stats. print.filament_stats.clear(); @@ -935,20 +860,14 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) print.total_extruded_volume = 0.; print.total_weight = 0.; print.total_cost = 0.; -//####################################################################################################################################################################### print.estimated_normal_print_time = m_normal_time_estimator.get_time_dhms(); -// print.estimated_default_print_time = m_default_time_estimator.get_time_dhms(); -//####################################################################################################################################################################### print.estimated_silent_print_time = m_silent_time_estimator_enabled ? m_silent_time_estimator.get_time_dhms() : "N/A"; for (const Extruder &extruder : m_writer.extruders()) { double used_filament = extruder.used_filament(); double extruded_volume = extruder.extruded_volume(); double filament_weight = extruded_volume * extruder.filament_density() * 0.001; double filament_cost = filament_weight * extruder.filament_cost() * 0.001; -//####################################################################################################################################################################### print.filament_stats.insert(std::pair(extruder.id(), (float)used_filament)); -// print.filament_stats.insert(std::pair(extruder.id(), used_filament)); -//####################################################################################################################################################################### _write_format(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001); if (filament_weight > 0.) { print.total_weight = print.total_weight + filament_weight; @@ -962,10 +881,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) print.total_extruded_volume = print.total_extruded_volume + extruded_volume; } _write_format(file, "; total filament cost = %.1lf\n", print.total_cost); -//####################################################################################################################################################################### _write_format(file, "; estimated printing time (normal mode) = %s\n", m_normal_time_estimator.get_time_dhms().c_str()); -// _write_format(file, "; estimated printing time (default mode) = %s\n", m_default_time_estimator.get_time_dhms().c_str()); -//####################################################################################################################################################################### if (m_silent_time_estimator_enabled) _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); @@ -1534,15 +1450,6 @@ void GCode::process_layer( // printf("G-code after filter:\n%s\n", out.c_str()); _write(file, gcode); - -//####################################################################################################################################################################### -// // after layer time estimation -// if (m_silent_time_estimator_enabled) -// { -// _write(file, m_default_time_estimator.get_elapsed_time_string().c_str()); -// _write(file, m_silent_time_estimator.get_elapsed_time_string().c_str()); -// } -//####################################################################################################################################################################### } void GCode::apply_print_config(const PrintConfig &print_config) @@ -2201,10 +2108,7 @@ void GCode::_write(FILE* file, const char *what) // writes string to file fwrite(gcode, 1, ::strlen(gcode), file); // updates time estimator and gcode lines vector -//####################################################################################################################################################################### m_normal_time_estimator.add_gcode_block(gcode); -// m_default_time_estimator.add_gcode_block(gcode); -//####################################################################################################################################################################### if (m_silent_time_estimator_enabled) m_silent_time_estimator.add_gcode_block(gcode); } diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index d994e750f5..163ade82ff 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -133,10 +133,7 @@ public: m_last_height(GCodeAnalyzer::Default_Height), m_brim_done(false), m_second_layer_things_done(false), -//############################################################################################################3 m_normal_time_estimator(GCodeTimeEstimator::Normal), -// m_default_time_estimator(GCodeTimeEstimator::Default), -//############################################################################################################3 m_silent_time_estimator(GCodeTimeEstimator::Silent), m_silent_time_estimator_enabled(false), m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())) @@ -296,10 +293,7 @@ protected: std::pair m_last_obj_copy; // Time estimators -//############################################################################################################3 GCodeTimeEstimator m_normal_time_estimator; -// GCodeTimeEstimator m_default_time_estimator; -//############################################################################################################3 GCodeTimeEstimator m_silent_time_estimator; bool m_silent_time_estimator_enabled; diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 15a346399a..6e500bd4bb 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -12,7 +12,6 @@ static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float MILLISEC_TO_SEC = 0.001f; static const float INCHES_TO_MM = 25.4f; -//####################################################################################################################################################################### static const float NORMAL_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) static const float NORMAL_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 static const float NORMAL_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 @@ -22,16 +21,6 @@ static const float NORMAL_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.4f, 2.5f }; // fro static const float NORMAL_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) static const float NORMAL_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) static const float NORMAL_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent -//static const float DEFAULT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) -//static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 -//static const float DEFAULT_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 -//static const float DEFAULT_AXIS_MAX_FEEDRATE[] = { 500.0f, 500.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK2 -//static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f, 10000.0f }; // Prusa Firmware 1_75mm_MK2 -//static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from Prusa Firmware (Configuration.h) -//static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) -//static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) -//static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent -//####################################################################################################################################################################### static const float SILENT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) static const float SILENT_ACCELERATION = 1250.0f; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full @@ -45,13 +34,6 @@ static const float SILENT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 perc static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; -//############################################################################################################3 -//static const std::string ELAPSED_TIME_TAG_DEFAULT = ";_ELAPSED_TIME_DEFAULT: "; -//static const std::string ELAPSED_TIME_TAG_SILENT = ";_ELAPSED_TIME_SILENT: "; -// -//static const std::string REMAINING_TIME_CMD = "M73"; -//############################################################################################################3 - #if ENABLE_MOVE_STATS static const std::string MOVE_TYPE_STR[Slic3r::GCodeTimeEstimator::Block::Num_Types] = { @@ -278,98 +260,6 @@ namespace Slic3r { #endif // ENABLE_MOVE_STATS } -//############################################################################################################3 -// std::string GCodeTimeEstimator::get_elapsed_time_string() -// { -// calculate_time(); -// switch (_mode) -// { -// default: -// case Default: -// return ELAPSED_TIME_TAG_DEFAULT + std::to_string(get_time()) + "\n"; -// case Silent: -// return ELAPSED_TIME_TAG_SILENT + std::to_string(get_time()) + "\n"; -// } -// } -// -// bool GCodeTimeEstimator::post_process_elapsed_times(const std::string& filename, float default_time, float silent_time) -// { -// boost::nowide::ifstream in(filename); -// if (!in.good()) -// throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for reading.\n")); -// -// std::string path_tmp = filename + ".times"; -// -// FILE* out = boost::nowide::fopen(path_tmp.c_str(), "wb"); -// if (out == nullptr) -// throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for writing.\n")); -// -// std::string line; -// while (std::getline(in, line)) -// { -// if (!in.good()) -// { -// fclose(out); -// throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n")); -// } -// -// // this function expects elapsed time for default and silent mode to be into two consecutive lines inside the gcode -// if (boost::contains(line, ELAPSED_TIME_TAG_DEFAULT)) -// { -// std::string default_elapsed_time_str = line.substr(ELAPSED_TIME_TAG_DEFAULT.length()); -// float elapsed_time = (float)atof(default_elapsed_time_str.c_str()); -// float remaining_time = default_time - elapsed_time; -// line = REMAINING_TIME_CMD + " P" + std::to_string((int)(100.0f * elapsed_time / default_time)); -// line += " R" + _get_time_minutes(remaining_time); -// -// std::string next_line; -// std::getline(in, next_line); -// if (!in.good()) -// { -// fclose(out); -// throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n")); -// } -// -// if (boost::contains(next_line, ELAPSED_TIME_TAG_SILENT)) -// { -// std::string silent_elapsed_time_str = next_line.substr(ELAPSED_TIME_TAG_SILENT.length()); -// float elapsed_time = (float)atof(silent_elapsed_time_str.c_str()); -// float remaining_time = silent_time - elapsed_time; -// line += " Q" + std::to_string((int)(100.0f * elapsed_time / silent_time)); -// line += " S" + _get_time_minutes(remaining_time); -// } -// else -// // found horphaned default elapsed time, skip the remaining time line output -// line = next_line; -// } -// else if (boost::contains(line, ELAPSED_TIME_TAG_SILENT)) -// // found horphaned silent elapsed time, skip the remaining time line output -// continue; -// -// line += "\n"; -// fwrite((const void*)line.c_str(), 1, line.length(), out); -// if (ferror(out)) -// { -// in.close(); -// fclose(out); -// boost::nowide::remove(path_tmp.c_str()); -// throw std::runtime_error(std::string("Remaining times estimation failed.\nIs the disk full?\n")); -// } -// } -// -// fclose(out); -// in.close(); -// -// boost::nowide::remove(filename.c_str()); -// if (boost::nowide::rename(path_tmp.c_str(), filename.c_str()) != 0) -// throw std::runtime_error(std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + filename + '\n' + -// "Is " + path_tmp + " locked?" + '\n'); -// -// return true; -// } -//############################################################################################################3 - -//################################################################################################################# bool GCodeTimeEstimator::post_process_remaining_times(const std::string& filename, float interval) { boost::nowide::ifstream in(filename); @@ -481,7 +371,6 @@ namespace Slic3r { return true; } -//################################################################################################################# void GCodeTimeEstimator::set_axis_position(EAxis axis, float position) { @@ -500,7 +389,6 @@ namespace Slic3r { void GCodeTimeEstimator::set_axis_max_jerk(EAxis axis, float jerk) { -//############################################################################################################3 if ((axis == X) || (axis == Y)) { switch (_mode) @@ -518,7 +406,7 @@ namespace Slic3r { } } } -//############################################################################################################3 + _state.axis[axis].max_jerk = jerk; } @@ -642,17 +530,6 @@ namespace Slic3r { return _state.e_local_positioning_type; } -//################################################################################################################# - bool GCodeTimeEstimator::are_remaining_times_enabled() const - { - return _state.remaining_times_enabled; - } - - void GCodeTimeEstimator::set_remaining_times_enabled(bool enable) - { - _state.remaining_times_enabled = enable; - } - int GCodeTimeEstimator::get_g1_line_id() const { return _state.g1_line_id; @@ -667,7 +544,6 @@ namespace Slic3r { { _state.g1_line_id = 0; } -//################################################################################################################# void GCodeTimeEstimator::add_additional_time(float timeSec) { @@ -690,22 +566,13 @@ namespace Slic3r { set_dialect(gcfRepRap); set_global_positioning_type(Absolute); set_e_local_positioning_type(Absolute); -//################################################################################################################# - set_remaining_times_enabled(false); -//################################################################################################################# switch (_mode) { default: -//############################################################################################################3 case Normal: -// case Default: -//############################################################################################################3 { -//############################################################################################################3 _set_default_as_normal(); -// _set_default_as_default(); -//############################################################################################################3 break; } case Silent: @@ -752,10 +619,8 @@ namespace Slic3r { set_additional_time(0.0f); -//############################################################################################################3 reset_g1_line_id(); _g1_line_ids.clear(); -//############################################################################################################3 } void GCodeTimeEstimator::_reset_time() @@ -768,12 +633,8 @@ namespace Slic3r { _blocks.clear(); } -//############################################################################################################3 void GCodeTimeEstimator::_set_default_as_normal() -// void GCodeTimeEstimator::_set_default_as_default() -//############################################################################################################3 { -//############################################################################################################3 set_feedrate(NORMAL_FEEDRATE); set_acceleration(NORMAL_ACCELERATION); set_retract_acceleration(NORMAL_RETRACT_ACCELERATION); @@ -788,41 +649,6 @@ namespace Slic3r { set_axis_max_acceleration(axis, NORMAL_AXIS_MAX_ACCELERATION[a]); set_axis_max_jerk(axis, NORMAL_AXIS_MAX_JERK[a]); } - -// std::cout << "Normal Default" << std::endl; -// std::cout << "set_acceleration " << NORMAL_ACCELERATION << std::endl; -// std::cout << "set_retract_acceleration " << NORMAL_RETRACT_ACCELERATION << std::endl; -// std::cout << "set_minimum_feedrate " << NORMAL_MINIMUM_FEEDRATE << std::endl; -// std::cout << "set_minimum_travel_feedrate " << NORMAL_MINIMUM_TRAVEL_FEEDRATE << std::endl; -// std::cout << "set_axis_max_acceleration X " << NORMAL_AXIS_MAX_ACCELERATION[X] << std::endl; -// std::cout << "set_axis_max_acceleration Y " << NORMAL_AXIS_MAX_ACCELERATION[Y] << std::endl; -// std::cout << "set_axis_max_acceleration Z " << NORMAL_AXIS_MAX_ACCELERATION[Z] << std::endl; -// std::cout << "set_axis_max_acceleration E " << NORMAL_AXIS_MAX_ACCELERATION[E] << std::endl; -// std::cout << "set_axis_max_feedrate X " << NORMAL_AXIS_MAX_FEEDRATE[X] << std::endl; -// std::cout << "set_axis_max_feedrate Y " << NORMAL_AXIS_MAX_FEEDRATE[Y] << std::endl; -// std::cout << "set_axis_max_feedrate Z " << NORMAL_AXIS_MAX_FEEDRATE[Z] << std::endl; -// std::cout << "set_axis_max_feedrate E " << NORMAL_AXIS_MAX_FEEDRATE[E] << std::endl; -// std::cout << "set_axis_max_jerk X " << NORMAL_AXIS_MAX_JERK[X] << std::endl; -// std::cout << "set_axis_max_jerk Y " << NORMAL_AXIS_MAX_JERK[Y] << std::endl; -// std::cout << "set_axis_max_jerk Z " << NORMAL_AXIS_MAX_JERK[Z] << std::endl; -// std::cout << "set_axis_max_jerk E " << NORMAL_AXIS_MAX_JERK[E] << std::endl; - - -// set_feedrate(DEFAULT_FEEDRATE); -// set_acceleration(DEFAULT_ACCELERATION); -// set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION); -// set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE); -// set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE); -// set_extrude_factor_override_percentage(DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE); -// -// for (unsigned char a = X; a < Num_Axis; ++a) -// { -// EAxis axis = (EAxis)a; -// set_axis_max_feedrate(axis, DEFAULT_AXIS_MAX_FEEDRATE[a]); -// set_axis_max_acceleration(axis, DEFAULT_AXIS_MAX_ACCELERATION[a]); -// set_axis_max_jerk(axis, DEFAULT_AXIS_MAX_JERK[a]); -// } -//############################################################################################################3 } void GCodeTimeEstimator::_set_default_as_silent() @@ -859,10 +685,7 @@ namespace Slic3r { _time += get_additional_time(); -//########################################################################################################################## for (Block& block : _blocks) -// for (const Block& block : _blocks) -//########################################################################################################################## { if (block.st_synchronized) continue; @@ -873,9 +696,7 @@ namespace Slic3r { block_time += block.cruise_time(); block_time += block.deceleration_time(); _time += block_time; -//########################################################################################################################## - block.elapsed_time = are_remaining_times_enabled() ? _time : -1.0f; -//########################################################################################################################## + block.elapsed_time = _time; MovesStatsMap::iterator it = _moves_stats.find(block.move_type); if (it == _moves_stats.end()) @@ -887,9 +708,7 @@ namespace Slic3r { _time += block.acceleration_time(); _time += block.cruise_time(); _time += block.deceleration_time(); -//########################################################################################################################## - block.elapsed_time = are_remaining_times_enabled() ? _time : -1.0f; -//########################################################################################################################## + block.elapsed_time = _time; #endif // ENABLE_MOVE_STATS } } @@ -1027,9 +846,7 @@ namespace Slic3r { void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) { -//############################################################################################################3 increment_g1_line_id(); -//############################################################################################################3 // updates axes positions from line EUnits units = get_units(); @@ -1218,9 +1035,7 @@ namespace Slic3r { // adds block to blocks list _blocks.emplace_back(block); -//############################################################################################################3 _g1_line_ids.insert(G1LineIdToBlockIdMap::value_type(get_g1_line_id(), (unsigned int)_blocks.size() - 1)); -//############################################################################################################3 } void GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index ef074f0738..0307b658e2 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -19,10 +19,7 @@ namespace Slic3r { public: enum EMode : unsigned char { -//####################################################################################################################################################################### Normal, -// Default, -//####################################################################################################################################################################### Silent }; @@ -79,11 +76,8 @@ namespace Slic3r { float additional_time; // s float minimum_feedrate; // mm/s float minimum_travel_feedrate; // mm/s - float extrude_factor_override_percentage; -//################################################################################################################# - bool remaining_times_enabled; + float extrude_factor_override_percentage; unsigned int g1_line_id; -//################################################################################################################# }; public: @@ -146,9 +140,7 @@ namespace Slic3r { FeedrateProfile feedrate; Trapezoid trapezoid; -//################################################################################################################# float elapsed_time; -//################################################################################################################# bool st_synchronized; @@ -244,25 +236,12 @@ namespace Slic3r { // Calculates the time estimate from the gcode contained in given list of gcode lines void calculate_time_from_lines(const std::vector& gcode_lines); -//############################################################################################################3 -// // Calculates the time estimate from the gcode lines added using add_gcode_line() or add_gcode_block() -// // and returns it in a formatted string -// std::string get_elapsed_time_string(); -//############################################################################################################3 - -//############################################################################################################3 -// // Converts elapsed time lines, contained in the gcode saved with the given filename, into remaining time commands -// static bool post_process_elapsed_times(const std::string& filename, float default_time, float silent_time); -//############################################################################################################3 - -//################################################################################################################# // Process the gcode contained in the file with the given filename, // placing in it new lines (M73) containing the remaining time, at the given interval in seconds // and saving the result back in the same file // This time estimator should have been already used to calculate the time estimate for the gcode // contained in the given file before to call this method bool post_process_remaining_times(const std::string& filename, float interval_sec); -//################################################################################################################# // Set current position on the given axis with the given value void set_axis_position(EAxis axis, float position); @@ -308,14 +287,9 @@ namespace Slic3r { void set_e_local_positioning_type(EPositioningType type); EPositioningType get_e_local_positioning_type() const; -//################################################################################################################# - bool are_remaining_times_enabled() const; - void set_remaining_times_enabled(bool enable); - int get_g1_line_id() const; void increment_g1_line_id(); void reset_g1_line_id(); -//################################################################################################################# void add_additional_time(float timeSec); void set_additional_time(float timeSec); @@ -340,10 +314,7 @@ namespace Slic3r { void _reset_time(); void _reset_blocks(); -//############################################################################################################3 void _set_default_as_normal(); -// void _set_default_as_default(); -//############################################################################################################3 void _set_default_as_silent(); void _set_blocks_st_synchronize(bool state); diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 9fd59d690e..eec5c24785 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -235,10 +235,7 @@ public: PrintRegionPtrs regions; PlaceholderParser placeholder_parser; // TODO: status_cb -//####################################################################################################################################################################### std::string estimated_normal_print_time; -// std::string estimated_default_print_time; -//####################################################################################################################################################################### std::string estimated_silent_print_time; double total_used_filament, total_extruded_volume, total_cost, total_weight; std::map filament_stats; diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 49568e0ab2..387a5b241f 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -936,10 +936,7 @@ PrintConfigDef::PrintConfigDef() def->sidetext = L("mm/s²"); def->min = 0; def->width = machine_limits_opt_width; -//################################################################################################################################## def->default_value = new ConfigOptionFloats{ 1500., 1250. }; -// def->default_value = new ConfigOptionFloats(1500., 1250.); -//################################################################################################################################## // M204 T... [mm/sec^2] def = this->add("machine_max_acceleration_retracting", coFloats); @@ -949,10 +946,7 @@ PrintConfigDef::PrintConfigDef() def->sidetext = L("mm/s²"); def->min = 0; def->width = machine_limits_opt_width; -//################################################################################################################################## def->default_value = new ConfigOptionFloats{ 1500., 1250. }; -// def->default_value = new ConfigOptionFloats(1500., 1250.); -//################################################################################################################################## def = this->add("max_fan_speed", coInts); def->label = L("Max"); diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index b286186244..aad27222e9 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -666,6 +666,7 @@ public: ConfigOptionString output_filename_format; ConfigOptionFloat perimeter_acceleration; ConfigOptionStrings post_process; + ConfigOptionString printer_model; ConfigOptionString printer_notes; ConfigOptionFloat resolution; ConfigOptionFloats retract_before_travel; @@ -736,6 +737,7 @@ protected: OPT_PTR(output_filename_format); OPT_PTR(perimeter_acceleration); OPT_PTR(post_process); + OPT_PTR(printer_model); OPT_PTR(printer_notes); OPT_PTR(resolution); OPT_PTR(retract_before_travel); From c34a713c8c05b7eb285219e5b90facc8e1ea300b Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 17 Jul 2018 10:41:17 +0200 Subject: [PATCH 20/26] Simplification of 1.40.1-rc2 fails to save the modified AMF settings #1035 --- xs/src/slic3r/GUI/Preset.cpp | 3 +++ xs/src/slic3r/GUI/Preset.hpp | 4 ---- xs/src/slic3r/GUI/PresetBundle.cpp | 15 ++++++--------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index f3cedd6939..e376a6ed2f 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -505,6 +505,9 @@ Preset& PresetCollection::load_external_preset( // Insert a new profile. Preset &preset = this->load_preset(path, new_name, std::move(cfg), select); preset.is_external = true; + if (&this->get_selected_preset() == &preset) + this->get_edited_preset().is_external = true; + return preset; } diff --git a/xs/src/slic3r/GUI/Preset.hpp b/xs/src/slic3r/GUI/Preset.hpp index 5faee08f1d..a2ee1d2eb0 100644 --- a/xs/src/slic3r/GUI/Preset.hpp +++ b/xs/src/slic3r/GUI/Preset.hpp @@ -353,10 +353,6 @@ public: // Generate a file path from a profile name. Add the ".ini" suffix if it is missing. std::string path_from_name(const std::string &new_name) const; - // update m_edited_preset.is_external value after loading preset for .ini, .gcode, .amf, .3mf - void update_edited_preset_is_external(bool is_external) { - m_edited_preset.is_external = is_external; } - protected: // Select a preset, if it exists. If it does not exist, select an invalid (-1) index. // This is a temporary state, which shall be fixed immediately by the following step. diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp index adca1b1534..b9a010659e 100644 --- a/xs/src/slic3r/GUI/PresetBundle.cpp +++ b/xs/src/slic3r/GUI/PresetBundle.cpp @@ -565,12 +565,11 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool size_t idx = (i_group == 0) ? 0 : num_extruders + 1; inherits = inherits_values[idx]; compatible_printers_condition = compatible_printers_condition_values[idx]; - if (is_external) { + if (is_external) presets.load_external_preset(name_or_path, name, config.opt_string((i_group == 0) ? "print_settings_id" : "printer_settings_id", true), config); - presets.update_edited_preset_is_external(true); - } else + else presets.load_preset(presets.path_from_name(name), name, config).save(); } @@ -583,10 +582,9 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool // Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets. inherits = inherits_values[1]; compatible_printers_condition = compatible_printers_condition_values[1]; - if (is_external) { + if (is_external) this->filaments.load_external_preset(name_or_path, name, old_filament_profile_names->values.front(), config); - this->filaments.update_edited_preset_is_external(true); - } else + else this->filaments.load_preset(this->filaments.path_from_name(name), name, config).save(); this->filament_presets.clear(); this->filament_presets.emplace_back(name); @@ -615,12 +613,11 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool cfg.opt_string("inherits", true) = inherits_values[i + 1]; // Load all filament presets, but only select the first one in the preset dialog. Preset *loaded = nullptr; - if (is_external) { + if (is_external) loaded = &this->filaments.load_external_preset(name_or_path, name, (i < old_filament_profile_names->values.size()) ? old_filament_profile_names->values[i] : "", std::move(cfg), i == 0); - this->filaments.update_edited_preset_is_external(true); - } else { + else { // Used by the config wizard when creating a custom setup. // Therefore this block should only be called for a single extruder. char suffix[64]; From 08529189c90922d021eddb62f96c6f604eb6ef05 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 17 Jul 2018 10:50:15 +0200 Subject: [PATCH 21/26] Changed time estimator default values --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 117 ++++++------------------ xs/src/libslic3r/GCodeTimeEstimator.hpp | 3 - 2 files changed, 28 insertions(+), 92 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 6e500bd4bb..285ed37bde 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -12,25 +12,15 @@ static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float MILLISEC_TO_SEC = 0.001f; static const float INCHES_TO_MM = 25.4f; -static const float NORMAL_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) -static const float NORMAL_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 -static const float NORMAL_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 -static const float NORMAL_AXIS_MAX_FEEDRATE[] = { 500.0f, 500.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK2 -static const float NORMAL_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f, 10000.0f }; // Prusa Firmware 1_75mm_MK2 -static const float NORMAL_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.4f, 2.5f }; // from Prusa Firmware (Configuration.h) -static const float NORMAL_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) -static const float NORMAL_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) -static const float NORMAL_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent - -static const float SILENT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) -static const float SILENT_ACCELERATION = 1250.0f; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full -static const float SILENT_RETRACT_ACCELERATION = 1250.0f; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full -static const float SILENT_AXIS_MAX_FEEDRATE[] = { 200.0f, 200.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full -static const float SILENT_AXIS_MAX_ACCELERATION[] = { 1000.0f, 1000.0f, 200.0f, 5000.0f }; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full -static const float SILENT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.4f, 2.5f }; // from Prusa Firmware (Configuration.h) -static const float SILENT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) -static const float SILENT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) -static const float SILENT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent +static const float DEFAULT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) +static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 +static const float DEFAULT_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 +static const float DEFAULT_AXIS_MAX_FEEDRATE[] = { 500.0f, 500.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK2 +static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f, 10000.0f }; // Prusa Firmware 1_75mm_MK2 +static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.4f, 2.5f }; // from Prusa Firmware (Configuration.h) +static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; @@ -389,24 +379,6 @@ namespace Slic3r { void GCodeTimeEstimator::set_axis_max_jerk(EAxis axis, float jerk) { - if ((axis == X) || (axis == Y)) - { - switch (_mode) - { - default: - case Normal: - { - jerk = std::min(jerk, NORMAL_AXIS_MAX_JERK[axis]); - break; - } - case Silent: - { - jerk = std::min(jerk, SILENT_AXIS_MAX_JERK[axis]); - break; - } - } - } - _state.axis[axis].max_jerk = jerk; } @@ -567,19 +539,19 @@ namespace Slic3r { set_global_positioning_type(Absolute); set_e_local_positioning_type(Absolute); - switch (_mode) + set_feedrate(DEFAULT_FEEDRATE); + set_acceleration(DEFAULT_ACCELERATION); + set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION); + set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE); + set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE); + set_extrude_factor_override_percentage(DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE); + + for (unsigned char a = X; a < Num_Axis; ++a) { - default: - case Normal: - { - _set_default_as_normal(); - break; - } - case Silent: - { - _set_default_as_silent(); - break; - } + EAxis axis = (EAxis)a; + set_axis_max_feedrate(axis, DEFAULT_AXIS_MAX_FEEDRATE[a]); + set_axis_max_acceleration(axis, DEFAULT_AXIS_MAX_ACCELERATION[a]); + set_axis_max_jerk(axis, DEFAULT_AXIS_MAX_JERK[a]); } } @@ -633,42 +605,6 @@ namespace Slic3r { _blocks.clear(); } - void GCodeTimeEstimator::_set_default_as_normal() - { - set_feedrate(NORMAL_FEEDRATE); - set_acceleration(NORMAL_ACCELERATION); - set_retract_acceleration(NORMAL_RETRACT_ACCELERATION); - set_minimum_feedrate(NORMAL_MINIMUM_FEEDRATE); - set_minimum_travel_feedrate(NORMAL_MINIMUM_TRAVEL_FEEDRATE); - set_extrude_factor_override_percentage(NORMAL_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE); - - for (unsigned char a = X; a < Num_Axis; ++a) - { - EAxis axis = (EAxis)a; - set_axis_max_feedrate(axis, NORMAL_AXIS_MAX_FEEDRATE[a]); - set_axis_max_acceleration(axis, NORMAL_AXIS_MAX_ACCELERATION[a]); - set_axis_max_jerk(axis, NORMAL_AXIS_MAX_JERK[a]); - } - } - - void GCodeTimeEstimator::_set_default_as_silent() - { - set_feedrate(SILENT_FEEDRATE); - set_acceleration(SILENT_ACCELERATION); - set_retract_acceleration(SILENT_RETRACT_ACCELERATION); - set_minimum_feedrate(SILENT_MINIMUM_FEEDRATE); - set_minimum_travel_feedrate(SILENT_MINIMUM_TRAVEL_FEEDRATE); - set_extrude_factor_override_percentage(SILENT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE); - - for (unsigned char a = X; a < Num_Axis; ++a) - { - EAxis axis = (EAxis)a; - set_axis_max_feedrate(axis, SILENT_AXIS_MAX_FEEDRATE[a]); - set_axis_max_acceleration(axis, SILENT_AXIS_MAX_ACCELERATION[a]); - set_axis_max_jerk(axis, SILENT_AXIS_MAX_JERK[a]); - } - } - void GCodeTimeEstimator::_set_blocks_st_synchronize(bool state) { for (Block& block : _blocks) @@ -896,13 +832,16 @@ namespace Slic3r { if (_curr.abs_axis_feedrate[a] > 0.0f) min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / _curr.abs_axis_feedrate[a]); } - + block.feedrate.cruise = min_feedrate_factor * _curr.feedrate; - for (unsigned char a = X; a < Num_Axis; ++a) + if (min_feedrate_factor < 1.0f) { - _curr.axis_feedrate[a] *= min_feedrate_factor; - _curr.abs_axis_feedrate[a] *= min_feedrate_factor; + for (unsigned char a = X; a < Num_Axis; ++a) + { + _curr.axis_feedrate[a] *= min_feedrate_factor; + _curr.abs_axis_feedrate[a] *= min_feedrate_factor; + } } // calculates block acceleration diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 0307b658e2..9b1a38985a 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -314,9 +314,6 @@ namespace Slic3r { void _reset_time(); void _reset_blocks(); - void _set_default_as_normal(); - void _set_default_as_silent(); - void _set_blocks_st_synchronize(bool state); // Calculates the time estimate From 86ba75d69253ec443e29bb0ecb0b46c163f92d8e Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Jul 2018 12:04:06 +0200 Subject: [PATCH 22/26] New objectfunction that makes a proper circle shaped pile on arrange. --- xs/src/libnest2d/CMakeLists.txt | 4 +- xs/src/libnest2d/examples/main.cpp | 21 +-- .../libnest2d/libnest2d/placers/nfpplacer.hpp | 103 ++++++-------- .../libnest2d/selections/djd_heuristic.hpp | 72 ++++++---- xs/src/libslic3r/Model.cpp | 134 ++++++------------ 5 files changed, 146 insertions(+), 188 deletions(-) diff --git a/xs/src/libnest2d/CMakeLists.txt b/xs/src/libnest2d/CMakeLists.txt index db4f5d99f2..bfdb551fc5 100644 --- a/xs/src/libnest2d/CMakeLists.txt +++ b/xs/src/libnest2d/CMakeLists.txt @@ -82,8 +82,8 @@ if(LIBNEST2D_OPTIMIZER_BACKEND STREQUAL "nlopt") ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/optimizers/genetic.hpp ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/optimizers/nlopt_boilerplate.hpp) list(APPEND LIBNEST2D_LIBRARIES ${NLopt_LIBS} - # Threads::Threads - ) +# Threads::Threads + ) list(APPEND LIBNEST2D_HEADERS ${NLopt_INCLUDE_DIR}) endif() diff --git a/xs/src/libnest2d/examples/main.cpp b/xs/src/libnest2d/examples/main.cpp index 3d3f30b76d..4623a6add7 100644 --- a/xs/src/libnest2d/examples/main.cpp +++ b/xs/src/libnest2d/examples/main.cpp @@ -84,7 +84,8 @@ void arrangeRectangles() { // {{0, 0}, {0, 20*SCALE}, {10*SCALE, 0}, {0, 0}} // }; - std::vector crasher = { + std::vector crasher = + { { {-5000000, 8954050}, {5000000, 8954050}, @@ -527,12 +528,12 @@ void arrangeRectangles() { }; std::vector input; -// input.insert(input.end(), prusaParts().begin(), prusaParts().end()); + input.insert(input.end(), prusaParts().begin(), prusaParts().end()); // input.insert(input.end(), prusaExParts().begin(), prusaExParts().end()); // input.insert(input.end(), stegoParts().begin(), stegoParts().end()); // input.insert(input.end(), rects.begin(), rects.end()); // input.insert(input.end(), proba.begin(), proba.end()); - input.insert(input.end(), crasher.begin(), crasher.end()); +// input.insert(input.end(), crasher.begin(), crasher.end()); Box bin(250*SCALE, 210*SCALE); @@ -545,18 +546,18 @@ void arrangeRectangles() { Packer::PlacementConfig pconf; pconf.alignment = Placer::Config::Alignment::CENTER; + pconf.starting_point = Placer::Config::Alignment::CENTER; pconf.rotations = {0.0/*, Pi/2.0, Pi, 3*Pi/2*/}; pconf.object_function = [&bin](Placer::Pile pile, double area, double norm, double penality) { auto bb = ShapeLike::boundingBox(pile); - double diameter = PointLike::distance(bb.minCorner(), - bb.maxCorner()); - - // We will optimize to the diameter of the circle around the bounding - // box and use the norming factor to get rid of the physical dimensions - double score = diameter / norm; + auto& sh = pile.back(); + auto rv = Nfp::referenceVertex(sh); + auto c = bin.center(); + auto d = PointLike::distance(rv, c); + double score = double(d)/norm; // If it does not fit into the print bed we will beat it // with a large penality @@ -568,7 +569,9 @@ void arrangeRectangles() { Packer::SelectionConfig sconf; // sconf.allow_parallel = false; // sconf.force_parallel = false; +// sconf.try_triplets = true; // sconf.try_reverse_order = true; +// sconf.waste_increment = 0.1; arrange.configure(pconf, sconf); diff --git a/xs/src/libnest2d/libnest2d/placers/nfpplacer.hpp b/xs/src/libnest2d/libnest2d/placers/nfpplacer.hpp index 5ddb3a98d8..d6bd154dba 100644 --- a/xs/src/libnest2d/libnest2d/placers/nfpplacer.hpp +++ b/xs/src/libnest2d/libnest2d/placers/nfpplacer.hpp @@ -26,11 +26,20 @@ struct NfpPConfig { /// Where to align the resulting packed pile Alignment alignment; + Alignment starting_point; + std::function&, double, double, double)> object_function; + /** + * @brief The quality of search for an optimal placement. + * This is a compromise slider between quality and speed. Zero is the + * fast and poor solution while 1.0 is the slowest but most accurate. + */ + float accuracy = 1.0; + NfpPConfig(): rotations({0.0, Pi/2.0, Pi, 3*Pi/2}), - alignment(Alignment::CENTER) {} + alignment(Alignment::CENTER), starting_point(Alignment::CENTER) {} }; // A class for getting a point on the circumference of the polygon (in log time) @@ -39,14 +48,6 @@ template class EdgeCache { using Coord = TCoord; using Edge = _Segment; -// enum Corners { -// BOTTOM, -// LEFT, -// RIGHT, -// TOP, -// NUM_CORNERS -// }; - mutable std::vector corners_; std::vector emap_; @@ -70,49 +71,9 @@ template class EdgeCache { void fetchCorners() const { if(!corners_.empty()) return; + // TODO Accuracy corners_ = distances_; - for(auto& d : corners_) { - d /= full_distance_; - } - -// corners_ = std::vector(NUM_CORNERS, 0.0); - -// std::vector idx_ud(emap_.size(), 0); -// std::vector idx_lr(emap_.size(), 0); - -// std::iota(idx_ud.begin(), idx_ud.end(), 0); -// std::iota(idx_lr.begin(), idx_lr.end(), 0); - -// std::sort(idx_ud.begin(), idx_ud.end(), -// [this](unsigned idx1, unsigned idx2) -// { -// const Vertex& v1 = emap_[idx1].first(); -// const Vertex& v2 = emap_[idx2].first(); - -// auto diff = getY(v1) - getY(v2); -// if(std::abs(diff) <= std::numeric_limits::epsilon()) -// return getX(v1) < getX(v2); - -// return diff < 0; -// }); - -// std::sort(idx_lr.begin(), idx_lr.end(), -// [this](unsigned idx1, unsigned idx2) -// { -// const Vertex& v1 = emap_[idx1].first(); -// const Vertex& v2 = emap_[idx2].first(); - -// auto diff = getX(v1) - getX(v2); -// if(std::abs(diff) <= std::numeric_limits::epsilon()) -// return getY(v1) < getY(v2); - -// return diff < 0; -// }); - -// corners_[BOTTOM] = distances_[idx_ud.front()]/full_distance_; -// corners_[TOP] = distances_[idx_ud.back()]/full_distance_; -// corners_[LEFT] = distances_[idx_lr.front()]/full_distance_; -// corners_[RIGHT] = distances_[idx_lr.back()]/full_distance_; + for(auto& d : corners_) d /= full_distance_; } public: @@ -167,12 +128,6 @@ public: inline double circumference() const BP2D_NOEXCEPT { return full_distance_; } -// inline double corner(Corners c) const BP2D_NOEXCEPT { -// assert(c < NUM_CORNERS); -// fetchCorners(); -// return corners_[c]; -// } - inline const std::vector& corners() const BP2D_NOEXCEPT { fetchCorners(); return corners_; @@ -400,7 +355,7 @@ public: opt::StopCriteria stopcr; stopcr.max_iterations = 1000; - stopcr.stoplimit = 0.01; + stopcr.stoplimit = 0.001; stopcr.type = opt::StopLimitType::RELATIVE; opt::TOptimizer solver(stopcr); @@ -518,11 +473,37 @@ private: void setInitialPosition(Item& item) { Box&& bb = item.boundingBox(); + Vertex ci, cb; - Vertex ci = bb.minCorner(); - Vertex cb = bin_.minCorner(); + switch(config_.starting_point) { + case Config::Alignment::CENTER: { + ci = bb.center(); + cb = bin_.center(); + break; + } + case Config::Alignment::BOTTOM_LEFT: { + ci = bb.minCorner(); + cb = bin_.minCorner(); + break; + } + case Config::Alignment::BOTTOM_RIGHT: { + ci = {getX(bb.maxCorner()), getY(bb.minCorner())}; + cb = {getX(bin_.maxCorner()), getY(bin_.minCorner())}; + break; + } + case Config::Alignment::TOP_LEFT: { + ci = {getX(bb.minCorner()), getY(bb.maxCorner())}; + cb = {getX(bin_.minCorner()), getY(bin_.maxCorner())}; + break; + } + case Config::Alignment::TOP_RIGHT: { + ci = bb.maxCorner(); + cb = bin_.maxCorner(); + break; + } + } - auto&& d = cb - ci; + auto d = cb - ci; item.translate(d); } diff --git a/xs/src/libnest2d/libnest2d/selections/djd_heuristic.hpp b/xs/src/libnest2d/libnest2d/selections/djd_heuristic.hpp index dcc029251a..1d233cf356 100644 --- a/xs/src/libnest2d/libnest2d/selections/djd_heuristic.hpp +++ b/xs/src/libnest2d/libnest2d/selections/djd_heuristic.hpp @@ -41,11 +41,24 @@ public: struct Config { /** - * If true, the algorithm will try to place pair and driplets in all - * possible order. + * If true, the algorithm will try to place pair and triplets in all + * possible order. It will have a hugely negative impact on performance. */ bool try_reverse_order = true; + /** + * @brief try_pairs Whether to try pairs of items to pack. It will add + * a quadratic component to the complexity. + */ + bool try_pairs = true; + + /** + * @brief Whether to try groups of 3 items to pack. This could be very + * slow for large number of items (>100) as it adds a cubic component + * to the complexity. + */ + bool try_triplets = false; + /** * The initial fill proportion of the bin area that will be filled before * trying items one by one, or pairs or triplets. @@ -151,8 +164,8 @@ public: return std::any_of(wrong_pairs.begin(), wrong_pairs.end(), [&i1, &i2](const TPair& pair) { - Item& pi1 = std::get<0>(pair), pi2 = std::get<1>(pair); - Item& ri1 = i1, ri2 = i2; + Item& pi1 = std::get<0>(pair), &pi2 = std::get<1>(pair); + Item& ri1 = i1, &ri2 = i2; return (&pi1 == &ri1 && &pi2 == &ri2) || (&pi1 == &ri2 && &pi2 == &ri1); }); @@ -172,7 +185,7 @@ public: Item& pi1 = std::get<0>(tripl); Item& pi2 = std::get<1>(tripl); Item& pi3 = std::get<2>(tripl); - Item& ri1 = i1, ri2 = i2, ri3 = i3; + Item& ri1 = i1, &ri2 = i2, &ri3 = i3; return (&pi1 == &ri1 && &pi2 == &ri2 && &pi3 == &ri3) || (&pi1 == &ri1 && &pi2 == &ri3 && &pi3 == &ri2) || (&pi1 == &ri2 && &pi2 == &ri1 && &pi3 == &ri3) || @@ -348,6 +361,10 @@ public: // Will be true if a succesfull pack can be made. bool ret = false; + auto area = [](const ItemListIt& it) { + return it->get().area(); + }; + while (it != endit && !ret) { // drill down 1st level // We need to determine in each iteration the largest, second @@ -361,7 +378,7 @@ public: // Check if there is enough free area for the item and the two // largest item - if(free_area - it->get().area() - area_of_two_largest > waste) + if(free_area - area(it) - area_of_two_largest > waste) break; // Determine the area of the two smallest item. @@ -373,7 +390,7 @@ public: double area_of_two_smallest = smallest.area() + second_smallest.area(); - if(it->get().area() + area_of_two_smallest > free_area) { + if(area(it) + area_of_two_smallest > free_area) { it++; continue; } @@ -384,16 +401,18 @@ public: it2 = not_packed.begin(); double rem2_area = free_area - largest.area(); - double a2_sum = it->get().area() + it2->get().area(); + double a2_sum = 0; while(it2 != endit && !ret && - rem2_area - a2_sum <= waste) { // Drill down level 2 + rem2_area - (a2_sum = area(it) + area(it2)) <= waste) { + // Drill down level 2 + + if(a2_sum != area(it) + area(it2)) throw -1; if(it == it2 || check_pair(wrong_pairs, *it, *it2)) { it2++; continue; } - a2_sum = it->get().area() + it2->get().area(); if(a2_sum + smallest.area() > free_area) { it2++; continue; } @@ -429,14 +448,13 @@ public: // The 'smallest' variable now could be identical with // it2 but we don't bother with that - if(!can_pack2) { it2++; continue; } - it3 = not_packed.begin(); - double a3_sum = a2_sum + it3->get().area(); + double a3_sum = 0; while(it3 != endit && !ret && - free_area - a3_sum <= waste) { // 3rd level + free_area - (a3_sum = a2_sum + area(it3)) <= waste) { + // 3rd level if(it3 == it || it3 == it2 || check_triplet(wrong_triplets, *it, *it2, *it3)) @@ -560,8 +578,11 @@ public: if(do_parallel) dout() << "Parallel execution..." << "\n"; + bool do_pairs = config_.try_pairs; + bool do_triplets = config_.try_triplets; + // The DJD heuristic algorithm itself: - auto packjob = [INITIAL_FILL_AREA, bin_area, w, + auto packjob = [INITIAL_FILL_AREA, bin_area, w, do_triplets, do_pairs, &tryOneByOne, &tryGroupsOfTwo, &tryGroupsOfThree, @@ -573,7 +594,7 @@ public: double waste = .0; bool lasttry = false; - while(!not_packed.empty() ) { + while(!not_packed.empty()) { {// Fill the bin up to INITIAL_FILL_PROPORTION of its capacity auto it = not_packed.begin(); @@ -594,26 +615,25 @@ public: // try pieses one by one while(tryOneByOne(placer, not_packed, waste, free_area, filled_area)) { - if(lasttry) std::cout << "Lasttry monopack" << std::endl; waste = 0; lasttry = false; makeProgress(placer, idx, 1); } // try groups of 2 pieses - while(tryGroupsOfTwo(placer, not_packed, waste, free_area, + while(do_pairs && + tryGroupsOfTwo(placer, not_packed, waste, free_area, filled_area)) { - if(lasttry) std::cout << "Lasttry bipack" << std::endl; waste = 0; lasttry = false; makeProgress(placer, idx, 2); } -// // try groups of 3 pieses -// while(tryGroupsOfThree(placer, not_packed, waste, free_area, -// filled_area)) { -// if(lasttry) std::cout << "Lasttry tripack" << std::endl; -// waste = 0; lasttry = false; -// makeProgress(placer, idx, 3); -// } + // try groups of 3 pieses + while(do_triplets && + tryGroupsOfThree(placer, not_packed, waste, free_area, + filled_area)) { + waste = 0; lasttry = false; + makeProgress(placer, idx, 3); + } waste += w; if(!lasttry && waste > free_area) lasttry = true; diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp index fc49d68af5..f63722e52f 100644 --- a/xs/src/libslic3r/Model.cpp +++ b/xs/src/libslic3r/Model.cpp @@ -19,7 +19,6 @@ #include #include -// #include #include "SVG.hpp" namespace Slic3r { @@ -308,7 +307,7 @@ namespace arr { using namespace libnest2d; -std::string toString(const Model& model) { +std::string toString(const Model& model, bool holes = true) { std::stringstream ss; ss << "{\n"; @@ -347,17 +346,17 @@ std::string toString(const Model& model) { // Holes: ss << "\t\t{\n"; -// for(auto h : expoly.holes) { -// ss << "\t\t\t{\n"; -// for(auto v : h.points) ss << "\t\t\t\t{" -// << v.x << ", " -// << v.y << "},\n"; -// { -// auto v = h.points.front(); -// ss << "\t\t\t\t{" << v.x << ", " << v.y << "},\n"; -// } -// ss << "\t\t\t},\n"; -// } + if(holes) for(auto h : expoly.holes) { + ss << "\t\t\t{\n"; + for(auto v : h.points) ss << "\t\t\t\t{" + << v.x << ", " + << v.y << "},\n"; + { + auto v = h.points.front(); + ss << "\t\t\t\t{" << v.x << ", " << v.y << "},\n"; + } + ss << "\t\t\t},\n"; + } ss << "\t\t},\n"; ss << "\t},\n"; @@ -476,58 +475,21 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb, // Create the arranger config auto min_obj_distance = static_cast(dist/SCALING_FACTOR); - // Benchmark bench; - - // std::cout << "Creating model siluett..." << std::endl; - - // bench.start(); // Get the 2D projected shapes with their 3D model instance pointers auto shapemap = arr::projectModelFromTop(model); - // bench.stop(); - - // std::cout << "Model siluett created in " << bench.getElapsedSec() - // << " seconds. " << "Min object distance = " << min_obj_distance << std::endl; - -// std::cout << "{" << std::endl; -// std::for_each(shapemap.begin(), shapemap.end(), -// [] (ShapeData2D::value_type& it) -// { -// std::cout << "\t{" << std::endl; -// Item& item = it.second; -// for(auto& v : item) { -// std::cout << "\t\t" << "{" << getX(v) -// << ", " << getY(v) << "},\n"; -// } -// std::cout << "\t}," << std::endl; -// }); -// std::cout << "}" << std::endl; -// return true; bool hasbin = bb != nullptr && bb->defined; double area_max = 0; - Item *biggest = nullptr; // Copy the references for the shapes only as the arranger expects a // sequence of objects convertible to Item or ClipperPolygon std::vector> shapes; shapes.reserve(shapemap.size()); std::for_each(shapemap.begin(), shapemap.end(), - [&shapes, min_obj_distance, &area_max, &biggest,hasbin] + [&shapes, min_obj_distance, &area_max, hasbin] (ShapeData2D::value_type& it) { - if(!hasbin) { - Item& item = it.second; - item.addOffset(min_obj_distance); - auto b = ShapeLike::boundingBox(item.transformedShape()); - auto a = b.width()*b.height(); - if(area_max < a) { - area_max = static_cast(a); - biggest = &item; - } - } - shapes.push_back(std::ref(it.second)); - }); Box bin; @@ -545,9 +507,6 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb, static_cast(bbb.max.x), static_cast(bbb.max.y) }); - } else { - // Just take the biggest item as bin... ? - bin = ShapeLike::boundingBox(biggest->transformedShape()); } // Will use the DJD selection heuristic with the BottomLeft placement @@ -562,20 +521,22 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb, // Align the arranged pile into the center of the bin pcfg.alignment = PConf::Alignment::CENTER; + // Start placing the items from the center of the print bed + pcfg.starting_point = PConf::Alignment::CENTER; + // TODO cannot use rotations until multiple objects of same geometry can // handle different rotations // arranger.useMinimumBoundigBoxRotation(); pcfg.rotations = { 0.0 }; // Magic: we will specify what is the goal of arrangement... - // In this case we override the default object function because we - // (apparently) don't care about pack efficiency and all we care is that the - // larger items go into the center of the pile and smaller items orbit it - // so the resulting pile has a circle-like shape. - // This is good for the print bed's heat profile. - // As a side effect, the arrange procedure is a lot faster (we do not need - // to calculate the convex hulls) - pcfg.object_function = [&bin]( + // In this case we override the default object to make the larger items go + // into the center of the pile and smaller items orbit it so the resulting + // pile has a circle-like shape. This is good for the print bed's heat + // profile. We alse sacrafice a bit of pack efficiency for this to work. As + // a side effect, the arrange procedure is a lot faster (we do not need to + // calculate the convex hulls) + pcfg.object_function = [bin, hasbin]( NfpPlacer::Pile pile, // The currently arranged pile double /*area*/, // Sum area of items (not needed) double norm, // A norming factor for physical dimensions @@ -583,14 +544,25 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb, { auto bb = ShapeLike::boundingBox(pile); - // We will optimize to the diameter of the circle around the bounding - // box and use the norming factor to get rid of the physical dimensions - double score = PointLike::distance(bb.minCorner(), - bb.maxCorner()) / norm; + // We get the current item that's being evaluated. + auto& sh = pile.back(); + + // We retrieve the reference point of this item + auto rv = Nfp::referenceVertex(sh); + + // We get the distance of the reference point from the center of the + // heat bed + auto c = bin.center(); + auto d = PointLike::distance(rv, c); + + // The score will be the normalized distance which will be minimized, + // effectively creating a circle shaped pile of items + double score = double(d)/norm; // If it does not fit into the print bed we will beat it - // with a large penality - if(!NfpPlacer::wouldFit(bb, bin)) score = 2*penality - score; + // with a large penality. If we would not do this, there would be only + // one big pile that doesn't care whether it fits onto the print bed. + if(hasbin && !NfpPlacer::wouldFit(bb, bin)) score = 2*penality - score; return score; }; @@ -601,18 +573,10 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb, // Set the progress indicator for the arranger. arranger.progressIndicator(progressind); - // std::cout << "Arranging model..." << std::endl; - // bench.start(); - // Arrange and return the items with their respective indices within the // input sequence. auto result = arranger.arrangeIndexed(shapes.begin(), shapes.end()); - // bench.stop(); - // std::cout << "Model arranged in " << bench.getElapsedSec() - // << " seconds." << std::endl; - - auto applyResult = [&shapemap](ArrangeResult::value_type& group, Coord batch_offset) { @@ -636,8 +600,6 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb, } }; - // std::cout << "Applying result..." << std::endl; - // bench.start(); if(first_bin_only) { applyResult(result.front(), 0); } else { @@ -657,9 +619,6 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb, batch_offset += stride; } } - // bench.stop(); - // std::cout << "Result applied in " << bench.getElapsedSec() - // << " seconds." << std::endl; for(auto objptr : model.objects) objptr->invalidate_bounding_box(); @@ -674,16 +633,11 @@ bool Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb, { bool ret = false; if(bb != nullptr && bb->defined) { + // Despite the new arrange is able to run without a specified bin, + // the perl testsuit still fails for this case. For now the safest + // thing to do is to use the new arrange only when a proper bin is + // specified. ret = arr::arrange(*this, dist, bb, false, progressind); -// std::fstream out("out.cpp", std::fstream::out); -// if(out.good()) { -// out << "const TestData OBJECTS = \n"; -// out << arr::toString(*this); -// } -// out.close(); -// SVG svg("out.svg"); -// arr::toSVG(svg, *this); -// svg.Close(); } else { // get the (transformed) size of each instance so that we take // into account their different transformations when packing From 50424e33c6645873ce423ca92527fa745d28a194 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Jul 2018 16:35:48 +0200 Subject: [PATCH 23/26] Safety check for firstfit for larger objects than the print bed. --- xs/src/libnest2d/libnest2d/selections/firstfit.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/xs/src/libnest2d/libnest2d/selections/firstfit.hpp b/xs/src/libnest2d/libnest2d/selections/firstfit.hpp index 8a8a09f910..2253a0dfee 100644 --- a/xs/src/libnest2d/libnest2d/selections/firstfit.hpp +++ b/xs/src/libnest2d/libnest2d/selections/firstfit.hpp @@ -55,6 +55,18 @@ public: this->progress_(--total); }; + // Safety test: try to pack each item into an empty bin. If it fails + // then it should be removed from the not_packed list + { auto it = store_.begin(); + while (it != store_.end()) { + Placer p(bin); + if(!p.pack(*it)) { + auto itmp = it++; + store_.erase(itmp); + } else it++; + } + } + for(auto& item : store_ ) { bool was_packed = false; while(!was_packed) { From 0660862058565ab3c4e3523ec554f38cb02987bc Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 17 Jul 2018 19:37:24 +0200 Subject: [PATCH 24/26] For the Marlin firmware, the machine envelope G-code is emitted based on the Slic3r printer profile. Also the bundled config has been updated, so that the machine envelope G-code values were removed and the new Slic3r printer profile values were updated with the former G-code values. Slic3r version has been bumped up to 1.41.0-alpha for the configuration files to work. --- resources/profiles/PrusaResearch.idx | 2 + resources/profiles/PrusaResearch.ini | 93 ++++++++++++++++------------ xs/src/libslic3r/GCode.cpp | 32 ++++++++++ xs/src/libslic3r/GCode.hpp | 1 + xs/src/libslic3r/PrintConfig.cpp | 8 +-- xs/src/libslic3r/libslic3r.h | 2 +- xs/src/slic3r/GUI/Tab.cpp | 15 +++-- 7 files changed, 105 insertions(+), 48 deletions(-) diff --git a/resources/profiles/PrusaResearch.idx b/resources/profiles/PrusaResearch.idx index 19a8ab17fe..d050ef39c0 100644 --- a/resources/profiles/PrusaResearch.idx +++ b/resources/profiles/PrusaResearch.idx @@ -1,3 +1,5 @@ +min_slic3r_version = 1.41.0-alpha +0.2.0-alpha min_slic3r_version = 1.40.0 0.1.6 Split the MK2.5 profile from the MK2S min_slic3r_version = 1.40.0-beta diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index e6d5d81873..7e2c783774 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -5,7 +5,7 @@ name = Prusa Research # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the Slic3r configuration to be downgraded. -config_version = 0.1.6 +config_version = 0.2.0-alpha # Where to get the updates from? config_update_url = https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch/ @@ -140,7 +140,7 @@ infill_extrusion_width = 0.25 perimeter_extrusion_width = 0.25 solid_infill_extrusion_width = 0.25 top_infill_extrusion_width = 0.25 -support_material_extrusion_width = 0.18 +support_material_extrusion_width = 0.2 support_material_interface_layers = 0 support_material_interface_spacing = 0.15 support_material_spacing = 1 @@ -155,6 +155,7 @@ infill_extrusion_width = 0.7 perimeter_extrusion_width = 0.65 solid_infill_extrusion_width = 0.65 top_infill_extrusion_width = 0.6 +support_material_extrusion_width = 0.55 [print:*soluble_support*] overhangs = 1 @@ -213,26 +214,18 @@ top_infill_extrusion_width = 0.4 [print:0.05mm ULTRADETAIL 0.25 nozzle] inherits = *0.05mm*; *0.25nozzle* compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 and num_extruders==1 -external_perimeter_extrusion_width = 0 -extrusion_width = 0.28 fill_density = 20% -first_layer_extrusion_width = 0.3 -infill_extrusion_width = 0 infill_speed = 20 max_print_speed = 100 -perimeter_extrusion_width = 0 perimeter_speed = 20 small_perimeter_speed = 15 -solid_infill_extrusion_width = 0 solid_infill_speed = 20 support_material_speed = 20 -top_infill_extrusion_width = 0 [print:0.05mm ULTRADETAIL 0.25 nozzle MK3] inherits = *0.05mm*; *0.25nozzle* compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 and num_extruders==1 fill_pattern = grid -top_infill_extrusion_width = 0.4 # XXXXXXXXXXXXXXXXXXXX # XXX--- 0.10mm ---XXX @@ -294,7 +287,6 @@ infill_speed = 200 max_print_speed = 200 perimeter_speed = 45 solid_infill_speed = 200 -top_infill_extrusion_width = 0.4 top_solid_infill_speed = 50 [print:0.10mm DETAIL 0.6 nozzle MK3] @@ -308,7 +300,6 @@ infill_speed = 200 max_print_speed = 200 perimeter_speed = 45 solid_infill_speed = 200 -top_infill_extrusion_width = 0.4 top_solid_infill_speed = 50 # XXXXXXXXXXXXXXXXXXXX @@ -358,7 +349,6 @@ perimeter_acceleration = 600 perimeter_speed = 25 small_perimeter_speed = 15 solid_infill_speed = 40 -support_material_extrusion_width = 0.2 top_solid_infill_speed = 30 [print:0.15mm OPTIMAL 0.6 nozzle] @@ -544,7 +534,6 @@ external_perimeter_extrusion_width = 0.6 external_perimeter_speed = 30 notes = Set your solluble extruder in Multiple Extruders > Support material/raft interface extruder perimeter_speed = 40 -support_material_extrusion_width = 0.55 support_material_interface_layers = 3 support_material_xy_spacing = 120% top_infill_extrusion_width = 0.57 @@ -912,6 +901,23 @@ end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbe extruder_colour = #FFFF00 extruder_offset = 0x0 gcode_flavor = marlin +silent_mode = 0 +machine_max_acceleration_e = 10000 +machine_max_acceleration_extruding = 1500 +machine_max_acceleration_retracting = 1500 +machine_max_acceleration_x = 9000 +machine_max_acceleration_y = 9000 +machine_max_acceleration_z = 500 +machine_max_feedrate_e = 120 +machine_max_feedrate_x = 500 +machine_max_feedrate_y = 500 +machine_max_feedrate_z = 12 +machine_max_jerk_e = 2.5 +machine_max_jerk_x = 10 +machine_max_jerk_y = 10 +machine_max_jerk_z = 0.2 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25 min_layer_height = 0.07 @@ -935,7 +941,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -971,7 +977,7 @@ printer_model = MK2SMM inherits = *multimaterial* end_gcode = G1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n\n printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 default_print_profile = 0.15mm OPTIMAL default_filament_profile = Prusa PLA @@ -981,7 +987,7 @@ end_gcode = {if not has_wipe_tower}\n; Pull the filament into the cooling tubes. extruder_colour = #FFAA55;#5182DB;#4ECDD3;#FB7259 nozzle_diameter = 0.4,0.4,0.4,0.4 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 variable_layer_height = 0 default_print_profile = 0.15mm OPTIMAL default_filament_profile = Prusa PLA @@ -1005,7 +1011,7 @@ printer_variant = 0.25 default_print_profile = 0.10mm DETAIL 0.25 nozzle [printer:Original Prusa i3 MK2 0.6 nozzle] -inherits = *common*; *0.6nozzle* +inherits = *common* max_layer_height = 0.35 min_layer_height = 0.1 nozzle_diameter = 0.6 @@ -1020,7 +1026,7 @@ default_print_profile = 0.20mm NORMAL 0.6 nozzle inherits = *mm-single* [printer:Original Prusa i3 MK2 MM Single Mode 0.6 nozzle] -inherits = *mm-single*; *0.6nozzle* +inherits = *mm-single* nozzle_diameter = 0.6 printer_variant = 0.6 default_print_profile = 0.20mm NORMAL 0.6 nozzle @@ -1030,7 +1036,7 @@ inherits = *mm-multi* nozzle_diameter = 0.4,0.4,0.4,0.4 [printer:Original Prusa i3 MK2 MultiMaterial 0.6 nozzle] -inherits = *mm-multi*; *0.6nozzle* +inherits = *mm-multi* nozzle_diameter = 0.6,0.6,0.6,0.6 printer_variant = 0.6 default_print_profile = 0.20mm NORMAL 0.6 nozzle @@ -1042,17 +1048,17 @@ default_print_profile = 0.20mm NORMAL 0.6 nozzle [printer:Original Prusa i3 MK2.5] inherits = Original Prusa i3 MK2 printer_model = MK2.5 -start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5 0.25 nozzle] inherits = Original Prusa i3 MK2 0.25 nozzle printer_model = MK2.5 -start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5 0.6 nozzle] inherits = Original Prusa i3 MK2 0.6 nozzle printer_model = MK2.5 -start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 # XXXXXXXXXXXXXXXXX # XXX--- MK3 ---XXX @@ -1061,38 +1067,47 @@ start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM201 X9000 Y9000 Z50 [printer:Original Prusa i3 MK3] inherits = *common* end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200; home X axis\nM84 ; disable motors +machine_max_acceleration_e = 9000,9000 +machine_max_acceleration_extruding = 1250,960 +machine_max_acceleration_retracting = 1250,1250 +machine_max_acceleration_x = 1000,1000 +machine_max_acceleration_y = 1000,1000 +machine_max_acceleration_z = 1000,1000 +machine_max_feedrate_e = 120,120 +machine_max_feedrate_x = 200,172 +machine_max_feedrate_y = 200,172 +machine_max_feedrate_z = 12,12 +machine_max_jerk_e = 1.5,1.5 +machine_max_jerk_x = 8,8 +machine_max_jerk_y = 8,8 +machine_max_jerk_z = 0.4,0.4 +machine_min_extruding_rate = 0,0 +machine_min_travel_rate = 0,0 +silent_mode = 1 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n retract_lift_below = 209 max_print_height = 210 -start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif} +start_gcode = M115 U3.3.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif} printer_model = MK3 default_print_profile = 0.15mm OPTIMAL MK3 [printer:Original Prusa i3 MK3 0.25 nozzle] -inherits = *common* +inherits = Original Prusa i3 MK3 nozzle_diameter = 0.25 -end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200; home X axis\nM84 ; disable motors -printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n -retract_lift_below = 209 -max_print_height = 210 -start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif} -printer_model = MK3 +max_layer_height = 0.1 +min_layer_height = 0.05 printer_variant = 0.25 default_print_profile = 0.10mm DETAIL 0.25 nozzle MK3 [printer:Original Prusa i3 MK3 0.6 nozzle] -inherits = *common* +inherits = Original Prusa i3 MK3 nozzle_diameter = 0.6 -end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200; home X axis\nM84 ; disable motors -printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n -retract_lift_below = 209 -max_print_height = 210 -start_gcode = M115 U3.2.1 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif} -printer_model = MK3 +max_layer_height = 0.35 +min_layer_height = 0.1 printer_variant = 0.6 default_print_profile = 0.15mm OPTIMAL 0.6 nozzle MK3 # The obsolete presets will be removed when upgrading from the legacy configuration structure (up to Slic3r 1.39.2) to 1.40.0 and newer. [obsolete_presets] print="0.05mm DETAIL 0.25 nozzle";"0.05mm DETAIL MK3";"0.05mm DETAIL";"0.20mm NORMAL MK3";"0.35mm FAST MK3" -filament="ColorFabb Brass Bronze 1.75mm";"ColorFabb HT 1.75mm";"ColorFabb nGen 1.75mm";"ColorFabb Woodfil 1.75mm";"ColorFabb XT 1.75mm";"ColorFabb XT-CF20 1.75mm";"E3D PC-ABS 1.75mm";"Fillamentum ABS 1.75mm";"Fillamentum ASA 1.75mm";"Generic ABS 1.75mm";"Generic PET 1.75mm";"Generic PLA 1.75mm";"Prusa ABS 1.75mm";"Prusa HIPS 1.75mm";"Prusa PET 1.75mm";"Prusa PLA 1.75mm";"Taulman Bridge 1.75mm";"Taulman T-Glase 1.75mm" \ No newline at end of file +filament="ColorFabb Brass Bronze 1.75mm";"ColorFabb HT 1.75mm";"ColorFabb nGen 1.75mm";"ColorFabb Woodfil 1.75mm";"ColorFabb XT 1.75mm";"ColorFabb XT-CF20 1.75mm";"E3D PC-ABS 1.75mm";"Fillamentum ABS 1.75mm";"Fillamentum ASA 1.75mm";"Generic ABS 1.75mm";"Generic PET 1.75mm";"Generic PLA 1.75mm";"Prusa ABS 1.75mm";"Prusa HIPS 1.75mm";"Prusa PET 1.75mm";"Prusa PLA 1.75mm";"Taulman Bridge 1.75mm";"Taulman T-Glase 1.75mm" diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index e587c8e93a..98b3b40614 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -613,6 +613,9 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) m_cooling_buffer->set_current_extruder(initial_extruder_id); + // Emit machine envelope limits for the Marlin firmware. + this->print_machine_envelope(file, print); + // Disable fan. if (! print.config.cooling.get_at(initial_extruder_id) || print.config.disable_fan_first_layers.get_at(initial_extruder_id)) _write(file, m_writer.set_fan(0, true)); @@ -968,6 +971,35 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc return temp_set_by_gcode; } +// Print the machine envelope G-code for the Marlin firmware based on the "machine_max_xxx" parameters. +// Do not process this piece of G-code by the time estimator, it already knows the values through another sources. +void GCode::print_machine_envelope(FILE *file, Print &print) +{ + if (print.config.gcode_flavor.value == gcfMarlin) { + fprintf(file, "M201 X%d Y%d Z%d E%d ; sets maximum accelerations, mm/sec^2\n", + int(print.config.machine_max_acceleration_x.values.front() + 0.5), + int(print.config.machine_max_acceleration_y.values.front() + 0.5), + int(print.config.machine_max_acceleration_z.values.front() + 0.5), + int(print.config.machine_max_acceleration_e.values.front() + 0.5)); + fprintf(file, "M203 X%d Y%d Z%d E%d ; sets maximum feedrates, mm/sec\n", + int(print.config.machine_max_feedrate_x.values.front() + 0.5), + int(print.config.machine_max_feedrate_y.values.front() + 0.5), + int(print.config.machine_max_feedrate_z.values.front() + 0.5), + int(print.config.machine_max_feedrate_e.values.front() + 0.5)); + fprintf(file, "M204 S%d T%d ; sets acceleration (S) and retract acceleration (T), mm/sec^2\n", + int(print.config.machine_max_acceleration_extruding.values.front() + 0.5), + int(print.config.machine_max_acceleration_retracting.values.front() + 0.5)); + fprintf(file, "M205 X%.2lf Y%.2lf Z%.2lf E%.2lf ; sets the jerk limits, mm/sec\n", + print.config.machine_max_jerk_x.values.front(), + print.config.machine_max_jerk_y.values.front(), + print.config.machine_max_jerk_z.values.front(), + print.config.machine_max_jerk_e.values.front()); + fprintf(file, "M205 S%d T%d ; sets the minimum extruding and travel feed rate, mm/sec\n", + int(print.config.machine_min_extruding_rate.values.front() + 0.5), + int(print.config.machine_min_travel_rate.values.front() + 0.5)); + } +} + // Write 1st layer bed temperatures into the G-code. // Only do that if the start G-code does not already contain any M-code controlling an extruder temperature. // M140 - Set Extruder Temperature diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index 7bc5257315..8b40385e64 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -327,6 +327,7 @@ protected: void _write_format(FILE* file, const char* format, ...); std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1); + void print_machine_envelope(FILE *file, Print &print); void _print_first_layer_bed_temperature(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); void _print_first_layer_extruder_temperatures(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); // this flag triggers first layer speeds diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index f541089a33..739d597cd6 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -907,10 +907,10 @@ PrintConfigDef::PrintConfigDef() }; std::vector axes { // name, max_feedrate, max_acceleration, max_jerk - { "x", { 500., 200. }, { 9000., 1000. }, { 10., 10. } }, - { "y", { 500., 200. }, { 9000., 1000. }, { 10., 10. } }, - { "z", { 12., 12. }, { 500., 200. }, { 0.2, 0.4 } }, - { "e", { 120., 120. }, { 10000., 5000. }, { 2.5, 2.5 } } + { "x", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } }, + { "y", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } }, + { "z", { 12., 12. }, { 500., 200. }, { 0.2, 0.4 } }, + { "e", { 120., 120. }, { 10000., 5000. }, { 2.5, 2.5 } } }; for (const AxisDefault &axis : axes) { std::string axis_upper = boost::to_upper_copy(axis.name); diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index b0c144efe2..e81b0c8af5 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -14,7 +14,7 @@ #include #define SLIC3R_FORK_NAME "Slic3r Prusa Edition" -#define SLIC3R_VERSION "1.40.1" +#define SLIC3R_VERSION "1.41.0-alpha" #define SLIC3R_BUILD "UNKNOWN" typedef int32_t coord_t; diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 911ec0cbed..5bd2876e77 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1900,11 +1900,18 @@ void TabPrinter::update(){ bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; - const std::string &printer_model = m_config->opt_string("printer_model"); - bool can_use_silent_mode = printer_model.empty() ? false : printer_model == "MK3"; // "true" only for MK3 printers + { + Field *sm = get_field("silent_mode"); + if (! is_marlin_flavor) + // Disable silent mode for non-marlin firmwares. + get_field("silent_mode")->toggle(false); + if (is_marlin_flavor) + sm->enable(); + else + sm->disable(); + } - get_field("silent_mode")->toggle(can_use_silent_mode && is_marlin_flavor); - if (can_use_silent_mode && m_use_silent_mode != m_config->opt_bool("silent_mode")) { + if (m_use_silent_mode != m_config->opt_bool("silent_mode")) { m_rebuild_kinematics_page = true; m_use_silent_mode = m_config->opt_bool("silent_mode"); } From c596c05765f07b8984a1e2af431c545f4bda3a88 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 17 Jul 2018 20:37:15 +0200 Subject: [PATCH 25/26] With the Marlin flavor, a "machine envelope limits" G-code section is emitted, which breaks some of the automatic tests. Changed the default firmware flavor to RepRap, so that the automatic tests will run. --- xs/src/libslic3r/PrintConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 739d597cd6..7064e19fec 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -772,7 +772,7 @@ PrintConfigDef::PrintConfigDef() def->enum_labels.push_back("Machinekit"); def->enum_labels.push_back("Smoothie"); def->enum_labels.push_back(L("No extrusion")); - def->default_value = new ConfigOptionEnum(gcfMarlin); + def->default_value = new ConfigOptionEnum(gcfRepRap); def = this->add("infill_acceleration", coFloat); def->label = L("Infill"); From 3bebe9f95458ec3562696001bfb8d6540e9c1215 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 17 Jul 2018 21:31:54 +0200 Subject: [PATCH 26/26] Restored the "Fix STL through Netfabb" functionality, which has been lost during some merge process. --- lib/Slic3r/GUI/Plater.pm | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 4d421dc4ab..d0d4969e6a 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1702,6 +1702,34 @@ sub export_object_stl { $self->statusbar->SetStatusText(L("STL file exported to ").$output_file); } +sub fix_through_netfabb { + my ($self) = @_; + my ($obj_idx, $object) = $self->selected_object; + return if !defined $obj_idx; + my $model_object = $self->{model}->objects->[$obj_idx]; + my $model_fixed = Slic3r::Model->new; + Slic3r::GUI::fix_model_by_win10_sdk_gui($model_object, $self->{print}, $model_fixed); + + my @new_obj_idx = $self->load_model_objects(@{$model_fixed->objects}); + return if !@new_obj_idx; + + foreach my $new_obj_idx (@new_obj_idx) { + my $o = $self->{model}->objects->[$new_obj_idx]; + $o->clear_instances; + $o->add_instance($_) for @{$model_object->instances}; + #$o->invalidate_bounding_box; + + if ($o->volumes_count == $model_object->volumes_count) { + for my $i (0..($o->volumes_count-1)) { + $o->get_volume($i)->config->apply($model_object->get_volume($i)->config); + } + } + #FIXME restore volumes and their configs, layer_height_ranges, layer_height_profile, layer_height_profile_valid, + } + + $self->remove($obj_idx); +} + sub export_amf { my ($self) = @_; return if !@{$self->{objects}}; @@ -2280,6 +2308,11 @@ sub object_menu { $frame->_append_menu_item($menu, L("Export object as STL…"), L('Export this single object as STL file'), sub { $self->export_object_stl; }, undef, 'brick_go.png'); + if (Slic3r::GUI::is_windows10) { + $frame->_append_menu_item($menu, L("Fix STL through Netfabb"), L('Fix the model by sending it to a Netfabb cloud service through Windows 10 API'), sub { + $self->fix_through_netfabb; + }, undef, 'brick_go.png'); + } return $menu; }