diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index febdff7e0..5c8c454aa 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -819,48 +819,54 @@ namespace DoExport { // this->print_machine_envelope(file, print); // shall be adjusted as well to produce a G-code block compatible with the particular firmware flavor. if (config.gcode_flavor.value == gcfMarlin) { - normal_time_estimator.set_max_acceleration((float)config.machine_max_acceleration_extruding.values[0]); - normal_time_estimator.set_retract_acceleration((float)config.machine_max_acceleration_retracting.values[0]); - normal_time_estimator.set_minimum_feedrate((float)config.machine_min_extruding_rate.values[0]); - normal_time_estimator.set_minimum_travel_feedrate((float)config.machine_min_travel_rate.values[0]); - normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)config.machine_max_acceleration_x.values[0]); - normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)config.machine_max_acceleration_y.values[0]); - normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)config.machine_max_acceleration_z.values[0]); - normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)config.machine_max_acceleration_e.values[0]); - normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)config.machine_max_feedrate_x.values[0]); - normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)config.machine_max_feedrate_y.values[0]); - normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)config.machine_max_feedrate_z.values[0]); - normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)config.machine_max_feedrate_e.values[0]); - normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)config.machine_max_jerk_x.values[0]); - normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)config.machine_max_jerk_y.values[0]); - normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)config.machine_max_jerk_z.values[0]); - normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)config.machine_max_jerk_e.values[0]); - + if (config.machine_limits_type.value != MachineLimitsUsage::Ignore) { + normal_time_estimator.set_max_acceleration((float)config.machine_max_acceleration_extruding.values[0]); + normal_time_estimator.set_retract_acceleration((float)config.machine_max_acceleration_retracting.values[0]); + normal_time_estimator.set_minimum_feedrate((float)config.machine_min_extruding_rate.values[0]); + normal_time_estimator.set_minimum_travel_feedrate((float)config.machine_min_travel_rate.values[0]); + normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)config.machine_max_acceleration_x.values[0]); + normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)config.machine_max_acceleration_y.values[0]); + normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)config.machine_max_acceleration_z.values[0]); + normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)config.machine_max_acceleration_e.values[0]); + normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)config.machine_max_feedrate_x.values[0]); + normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)config.machine_max_feedrate_y.values[0]); + normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)config.machine_max_feedrate_z.values[0]); + normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)config.machine_max_feedrate_e.values[0]); + normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)config.machine_max_jerk_x.values[0]); + normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)config.machine_max_jerk_y.values[0]); + normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)config.machine_max_jerk_z.values[0]); + normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)config.machine_max_jerk_e.values[0]); + } + if (silent_time_estimator_enabled) { silent_time_estimator.reset(); silent_time_estimator.set_dialect(config.gcode_flavor); silent_time_estimator.set_extrusion_axis(config.get_extrusion_axis()[0]); - /* "Stealth mode" values can be just a copy of "normal mode" values - * (when they aren't input for a printer preset). - * Thus, use back value from values, instead of second one, which could be absent - */ - silent_time_estimator.set_max_acceleration((float)config.machine_max_acceleration_extruding.values.back()); - silent_time_estimator.set_retract_acceleration((float)config.machine_max_acceleration_retracting.values.back()); - silent_time_estimator.set_minimum_feedrate((float)config.machine_min_extruding_rate.values.back()); - silent_time_estimator.set_minimum_travel_feedrate((float)config.machine_min_travel_rate.values.back()); - silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)config.machine_max_acceleration_x.values.back()); - silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)config.machine_max_acceleration_y.values.back()); - silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)config.machine_max_acceleration_z.values.back()); - silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)config.machine_max_acceleration_e.values.back()); - silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)config.machine_max_feedrate_x.values.back()); - silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)config.machine_max_feedrate_y.values.back()); - silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)config.machine_max_feedrate_z.values.back()); - silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)config.machine_max_feedrate_e.values.back()); - silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)config.machine_max_jerk_x.values.back()); - silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)config.machine_max_jerk_y.values.back()); - silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)config.machine_max_jerk_z.values.back()); - silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)config.machine_max_jerk_e.values.back()); + + if (config.machine_limits_type.value != MachineLimitsUsage::Ignore) { + /* "Stealth mode" values can be just a copy of "normal mode" values + * (when they aren't input for a printer preset). + * Thus, use back value from values, instead of second one, which could be absent + */ + silent_time_estimator.set_max_acceleration((float)config.machine_max_acceleration_extruding.values.back()); + silent_time_estimator.set_retract_acceleration((float)config.machine_max_acceleration_retracting.values.back()); + silent_time_estimator.set_minimum_feedrate((float)config.machine_min_extruding_rate.values.back()); + silent_time_estimator.set_minimum_travel_feedrate((float)config.machine_min_travel_rate.values.back()); + silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)config.machine_max_acceleration_x.values.back()); + silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)config.machine_max_acceleration_y.values.back()); + silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)config.machine_max_acceleration_z.values.back()); + silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)config.machine_max_acceleration_e.values.back()); + silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)config.machine_max_feedrate_x.values.back()); + silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)config.machine_max_feedrate_y.values.back()); + silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)config.machine_max_feedrate_z.values.back()); + silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)config.machine_max_feedrate_e.values.back()); + silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)config.machine_max_jerk_x.values.back()); + silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)config.machine_max_jerk_y.values.back()); + silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)config.machine_max_jerk_z.values.back()); + silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)config.machine_max_jerk_e.values.back()); + } + if (config.single_extruder_multi_material) { // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they // are considered to be active for the single extruder multi-material printers only. @@ -1694,7 +1700,7 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc // 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) { + if (print.config().gcode_flavor.value == gcfMarlin && print.config().machine_limits_type.value == MachineLimitsUsage::EmitToGCode) { 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), diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index ddcadf928..182cf1193 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -454,6 +454,21 @@ const std::vector& Preset::filament_options() return s_opts; } +const std::vector& Preset::machine_limits_options() +{ + static std::vector s_opts; + if (s_opts.empty()) { + s_opts = { + "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", + }; + } + return s_opts; +} + const std::vector& Preset::printer_options() { static std::vector s_opts; @@ -468,13 +483,10 @@ const std::vector& Preset::printer_options() "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction", "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height", "default_print_profile", "inherits", - "remaining_times", "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", - "thumbnails" + "remaining_times", "silent_mode", + "machine_limits_usage", "thumbnails" }; + s_opts.insert(s_opts.end(), Preset::machine_limits_options().begin(), Preset::machine_limits_options().end()); s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end()); } return s_opts; diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index e3e16b65d..5713b25c8 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -218,6 +218,8 @@ public: static const std::vector& printer_options(); // Nozzle options of the printer options. static const std::vector& nozzle_options(); + // Printer machine limits, those are contained in printer_options(). + static const std::vector& machine_limits_options(); static const std::vector& sla_printer_options(); static const std::vector& sla_material_options(); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 93d9cfbcf..f4b0de707 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1201,6 +1201,21 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert; def->set_default_value(new ConfigOptionBool(true)); + def = this->add("machine_limits_usage", coEnum); + def->label = L("How to apply"); + def->full_label = L("Purpose of Machine Limits"); + def->category = L("Machine limits"); + def->tooltip = L("How to apply the Machine Limits"); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("emit_to_gcode"); + def->enum_values.push_back("time_estimate_only"); + def->enum_values.push_back("ignore"); + def->enum_labels.push_back("Emit to G-code"); + def->enum_labels.push_back("Use for time estimate"); + def->enum_labels.push_back("Ignore"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionEnum(MachineLimitsUsage::EmitToGCode)); + { struct AxisDefault { std::string name; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 52e3bc38c..9151fd809 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -29,6 +29,13 @@ enum GCodeFlavor : unsigned char { gcfSmoothie, gcfNoExtrusion, }; +enum class MachineLimitsUsage { + EmitToGCode, + TimeEstimateOnly, + Ignore, + Count, +}; + enum PrintHostType { htOctoPrint, htDuet, htFlashAir, htAstroBox }; @@ -102,6 +109,16 @@ template<> inline const t_config_enum_values& ConfigOptionEnum::get return keys_map; } +template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { + static t_config_enum_values keys_map; + if (keys_map.empty()) { + keys_map["emit_to_gcode"] = int(MachineLimitsUsage::EmitToGCode); + keys_map["time_estimate_only"] = int(MachineLimitsUsage::TimeEstimateOnly); + keys_map["ignore"] = int(MachineLimitsUsage::Ignore); + } + return keys_map; +} + template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static t_config_enum_values keys_map; if (keys_map.empty()) { @@ -597,6 +614,8 @@ class MachineEnvelopeConfig : public StaticPrintConfig { STATIC_PRINT_CONFIG_CACHE(MachineEnvelopeConfig) public: + // Allowing the machine limits to be completely ignored or used just for time estimator. + ConfigOptionEnum machine_limits_type; // M201 X... Y... Z... E... [mm/sec^2] ConfigOptionFloats machine_max_acceleration_x; ConfigOptionFloats machine_max_acceleration_y; @@ -624,6 +643,7 @@ public: protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { + OPT_PTR(machine_limits_type); OPT_PTR(machine_max_acceleration_x); OPT_PTR(machine_max_acceleration_y); OPT_PTR(machine_max_acceleration_z); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 09e29caf9..5392deec9 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -1084,6 +1084,8 @@ boost::any& Choice::get_value() m_value = static_cast(ret_enum); else if (m_opt_id.compare("gcode_flavor") == 0) m_value = static_cast(ret_enum); + else if (m_opt_id.compare("machine_limits_usage") == 0) + m_value = static_cast(ret_enum); else if (m_opt_id.compare("support_material_pattern") == 0) m_value = static_cast(ret_enum); else if (m_opt_id.compare("seam_position") == 0) diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 6c76b6227..d822c9873 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -184,6 +184,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("gcode_flavor") == 0) config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); + else if (opt_key.compare("machine_limits_usage") == 0) + config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("support_material_pattern") == 0) config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("seam_position") == 0) diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 7080dc11c..8f593f1f2 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -821,6 +821,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config else if (opt_key == "gcode_flavor") { ret = static_cast(config.option>(opt_key)->value); } + else if (opt_key == "machine_limits_usage") { + ret = static_cast(config.option>(opt_key)->value); + } else if (opt_key == "support_material_pattern") { ret = static_cast(config.option>(opt_key)->value); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 924f3c8bb..d46413320 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2510,6 +2510,7 @@ void TabPrinter::build_sla() build_preset_description_line(optgroup.get()); } + /* void TabPrinter::update_serial_ports() { @@ -2556,7 +2557,18 @@ PageShp TabPrinter::build_kinematics_page() { auto page = add_options_page(L("Machine limits"), "cog", true); - if (m_use_silent_mode) { + auto optgroup = page->new_optgroup(L("General")); + { + optgroup->append_single_option_line("machine_limits_usage"); + Line line { "", "" }; + line.full_width = 1; + line.widget = [this](wxWindow* parent) { + return description_line_widget(parent, &m_machine_limits_description_line); + }; + optgroup->append_line(line); + } + + if (m_use_silent_mode) { // Legend for OptionsGroups auto optgroup = page->new_optgroup(""); optgroup->set_show_modified_btns_val(false); @@ -2583,7 +2595,7 @@ PageShp TabPrinter::build_kinematics_page() } std::vector axes{ "x", "y", "z", "e" }; - auto optgroup = page->new_optgroup(L("Maximum feedrates")); + optgroup = page->new_optgroup(L("Maximum feedrates")); for (const std::string &axis : axes) { append_option_line(optgroup, "machine_max_feedrate_" + axis); } @@ -2953,6 +2965,17 @@ void TabPrinter::toggle_options() toggle_option("retract_restart_extra_toolchange", have_multiple_extruders && toolchange_retraction, i); } + if (m_active_page->title() == "Machine limits") { + assert(m_config->option>("gcode_flavor")->value == gcfMarlin); + const auto *machine_limits_usage = m_config->option>("machine_limits_usage"); + bool enabled = machine_limits_usage->value != MachineLimitsUsage::Ignore; + bool silent_mode = m_config->opt_bool("silent_mode"); + int max_field = silent_mode ? 2 : 1; + for (const std::string &opt : Preset::machine_limits_options()) + for (int i = 0; i < max_field; ++ i) + toggle_option(opt, enabled, i); + update_machine_limits_description(machine_limits_usage->value); + } } void TabPrinter::update() @@ -3847,6 +3870,25 @@ void TabPrinter::apply_extruder_cnt_from_cache() } } +void TabPrinter::update_machine_limits_description(const MachineLimitsUsage usage) +{ + wxString text; + switch (usage) { + case MachineLimitsUsage::EmitToGCode: + text = _L("Machine limits will be emitted to G-code and used to estimate print time."); + break; + case MachineLimitsUsage::TimeEstimateOnly: + text = _L("Machine limits will NOT be emitted to G-code, however they will be used to estimate print time, \ + which may herefore not be accurate as the printer may apply a different set of machine limits."); + break; + case MachineLimitsUsage::Ignore: + text = _L("Machine limits are not set, therefore the print time estimate may not be accurate."); + break; + default: assert(false); + } + m_machine_limits_description_line->SetText(text); +} + void Tab::compatible_widget_reload(PresetDependencies &deps) { Field* field = this->get_field(deps.key_condition); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index a3711f453..bc396ae30 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -376,10 +376,6 @@ public: Tab(parent, _(L("Print Settings")), Slic3r::Preset::TYPE_PRINT) {} ~TabPrint() {} - ogStaticText* m_recommended_thin_wall_thickness_description_line = nullptr; - ogStaticText* m_top_bottom_shell_thickness_explanation = nullptr; - bool m_support_material_overhangs_queried = false; - void build() override; void reload_config() override; void update_description_lines() override; @@ -388,10 +384,16 @@ public: // void OnActivate() override; void clear_pages() override; bool supports_printer_technology(const PrinterTechnology tech) override { return tech == ptFFF; } + +private: + ogStaticText* m_recommended_thin_wall_thickness_description_line = nullptr; + ogStaticText* m_top_bottom_shell_thickness_explanation = nullptr; + bool m_support_material_overhangs_queried = false; }; class TabFilament : public Tab { +private: ogStaticText* m_volumetric_speed_description_line {nullptr}; ogStaticText* m_cooling_description_line {nullptr}; @@ -418,10 +420,13 @@ public: class TabPrinter : public Tab { +private: 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_rebuild_kinematics_page = false; + ogStaticText* m_machine_limits_description_line {nullptr}; + void update_machine_limits_description(const MachineLimitsUsage usage); std::vector m_pages_fff; std::vector m_pages_sla; diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index e7dec9fa8..e43f738c4 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -809,6 +809,8 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& return get_string_from_enum(opt_key, config, true); if (opt_key == "gcode_flavor") return get_string_from_enum(opt_key, config); + if (opt_key == "machine_limits_usage") + return get_string_from_enum(opt_key, config); if (opt_key == "ironing_type") return get_string_from_enum(opt_key, config); if (opt_key == "support_material_pattern")