diff --git a/doc/Calibration.md b/doc/Calibration.md index cede6ab376..efbfd2e386 100644 --- a/doc/Calibration.md +++ b/doc/Calibration.md @@ -315,8 +315,8 @@ The default value in Marlin is typically set to 0.08mm, which may be too high fo M205 J0.012 M500 ``` - 3. Recompile four MarlinFW - 1. In Configuration.h set: + 3. Recompile your MarlinFW + 1. In Configuration.h uncomment and set: ```cpp #define JUNCTION_DEVIATION_MM 0.012 // (mm) Distance from real junction edge ``` @@ -333,10 +333,10 @@ Because of the nature of these artifacts the methods to reduce them can be mecha *** *Credits:* -- *The Flowrate test and retraction test is inspired by [SuperSlicer](https://github.com/supermerill/SuperSlicer)* -- *The PA Line method is inspired by [K-factor Calibration Pattern](https://marlinfw.org/tools/lin_advance/k-factor.html)* -- *The PA Tower method is inspired by [Klipper](https://www.klipper3d.org/Pressure_Advance.html)* -- *The temp tower model is remixed from [Smart compact temperature calibration tower](https://www.thingiverse.com/thing:2729076) -- *The max flowrate test was inspired by Stefan(CNC Kitchen), and the model used in the test is a remix of his [Extrusion Test Structure](https://www.printables.com/model/342075-extrusion-test-structure). -- *ZV Input Shaping is inspired by [Marlin Input Shaping](https://marlinfw.org/docs/features/input_shaping.html) and [Ringing Tower 3D STL](https://marlinfw.org/assets/stl/ringing_tower.stl) +- *The Flowrate test and retraction test is inspired by [SuperSlicer](https://github.com/supermerill/SuperSlicer).* +- *The PA Line method is inspired by [K-factor Calibration Pattern](https://marlinfw.org/tools/lin_advance/k-factor.html).* +- *The PA Tower method is inspired by [Klipper](https://www.klipper3d.org/Pressure_Advance.html).* +- *The temp tower model is remixed from [Smart compact temperature calibration tower](https://www.thingiverse.com/thing:2729076).* +- *The max flowrate test was inspired by Stefan (CNC Kitchen), and the model used in the test is a remix of his [Extrusion Test Structure](https://www.printables.com/model/342075-extrusion-test-structure).* +- *ZV Input Shaping is inspired by [Marlin Input Shaping](https://marlinfw.org/docs/features/input_shaping.html) and [Ringing Tower 3D STL](https://marlinfw.org/assets/stl/ringing_tower.stl).* - *ChatGPT* ;) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 5764a21da6..020471033c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3139,6 +3139,9 @@ void GCode::print_machine_envelope(GCodeOutputStream &file, Print &print) print.config().machine_max_jerk_y.values.front() * factor, print.config().machine_max_jerk_z.values.front() * factor, print.config().machine_max_jerk_e.values.front() * factor); + + // New Marlin uses M205 J[mm] for junction deviation (only apply if it is > 0) + file.write_format(writer().set_junction_deviation(config().machine_max_junction_deviation.values.front()).c_str()); } } @@ -3783,9 +3786,6 @@ LayerResult GCode::process_layer( } case CalibMode::Calib_Input_shaping_freq: { if (m_layer_index == 1){ - if (print.config().gcode_flavor.value == gcfMarlinFirmware) { - gcode += writer().set_junction_deviation(0.25);//Set junction deviation at high value to maximize ringing. - } gcode += writer().set_input_shaping('A', print.calib_params().start, 0.f); } else { if (print.calib_params().freqStartX == print.calib_params().freqStartY && print.calib_params().freqEndX == print.calib_params().freqEndY) { @@ -3799,9 +3799,6 @@ LayerResult GCode::process_layer( } case CalibMode::Calib_Input_shaping_damp: { if (m_layer_index == 1){ - if (print.config().gcode_flavor.value == gcfMarlinFirmware) { - gcode += writer().set_junction_deviation(0.25); // Set junction deviation at high value to maximize ringing. - } gcode += writer().set_input_shaping('X', 0.f, print.calib_params().freqStartX); gcode += writer().set_input_shaping('Y', 0.f, print.calib_params().freqStartY); } else { @@ -3826,6 +3823,9 @@ LayerResult GCode::process_layer( gcode += m_writer.set_jerk_xy(m_config.initial_layer_jerk.value); } + if (m_writer.get_gcode_flavor() == gcfMarlinFirmware && m_config.default_junction_deviation.value > 0) { + gcode += m_writer.set_junction_deviation(m_config.default_junction_deviation.value); + } } if (! first_layer && ! m_second_layer_things_done) { diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 063785ce90..d93f609e11 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1038,6 +1038,10 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) if (machine_max_jerk_e != nullptr) m_time_processor.machine_limits.machine_max_jerk_e.values = machine_max_jerk_e->values; + const ConfigOptionFloats* machine_max_junction_deviation = config.option("machine_max_junction_deviation"); + if (machine_max_junction_deviation != nullptr) + m_time_processor.machine_limits.machine_max_junction_deviation.values = machine_max_junction_deviation->values; + const ConfigOptionFloats* machine_max_acceleration_extruding = config.option("machine_max_acceleration_extruding"); if (machine_max_acceleration_extruding != nullptr) m_time_processor.machine_limits.machine_max_acceleration_extruding.values = machine_max_acceleration_extruding->values; diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 0826721036..8d79fe1f40 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -37,6 +37,7 @@ void GCodeWriter::apply_print_config(const PrintConfig &print_config) if (use_mach_limits) { m_max_jerk_x = std::lrint(print_config.machine_max_jerk_x.values.front()); m_max_jerk_y = std::lrint(print_config.machine_max_jerk_y.values.front()); + m_max_junction_deviation = (print_config.machine_max_junction_deviation.values.front()); }; m_max_jerk_z = print_config.machine_max_jerk_z.values.front(); m_max_jerk_e = print_config.machine_max_jerk_e.values.front(); @@ -315,14 +316,22 @@ std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double je std::string GCodeWriter::set_junction_deviation(double junction_deviation){ std::ostringstream gcode; - if (FLAVOR_IS_NOT(gcfMarlinFirmware)) { - throw std::runtime_error("Junction deviation is only supported by Marlin firmware"); + if (FLAVOR_IS(gcfMarlinFirmware) && junction_deviation > 0 && m_max_junction_deviation > 0) { + // Clamp the junction deviation to the allowed maximum. + gcode << "M205 J"; + if (junction_deviation <= m_max_junction_deviation) { + gcode << std::fixed << std::setprecision(3) << junction_deviation; + } else { + gcode << std::fixed << std::setprecision(3) << m_max_junction_deviation; + } + if (GCodeWriter::full_gcode_comment) { + gcode << " ; Junction Deviation"; + } + gcode << "\n"; } - gcode << "M205 J" << std::fixed << std::setprecision(3) << junction_deviation << " ; Junction Deviation\n"; return gcode.str(); } - std::string GCodeWriter::set_pressure_advance(double pa) const { std::ostringstream gcode; diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 3b2133c456..e4eacd22d6 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -138,6 +138,7 @@ public: double m_last_jerk; double m_max_jerk_z; double m_max_jerk_e; + double m_max_junction_deviation; unsigned int m_travel_acceleration; unsigned int m_travel_jerk; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index d4caac27a7..6eac93c0a9 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -822,7 +822,7 @@ static std::vector s_Preset_print_options { "wall_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle", "wall_distribution_count", "min_feature_size", "min_bead_width", "post_process", "min_length_factor", "small_perimeter_speed", "small_perimeter_threshold","bridge_angle","internal_bridge_angle", "filter_out_gap_fill", "travel_acceleration","inner_wall_acceleration", "min_width_top_surface", - "default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", "top_surface_jerk", "initial_layer_jerk","travel_jerk", + "default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", "top_surface_jerk", "initial_layer_jerk","travel_jerk","default_junction_deviation", "top_solid_infill_flow_ratio","bottom_solid_infill_flow_ratio","only_one_wall_first_layer", "print_flow_ratio", "seam_gap", "role_based_wipe_speed", "wipe_speed", "accel_to_decel_enable", "accel_to_decel_factor", "wipe_on_loops", "wipe_before_external_loop", "bridge_density","internal_bridge_density", "precise_outer_wall", "overhang_speed_classic", "bridge_acceleration", @@ -875,6 +875,7 @@ static std::vector s_Preset_machine_limits_options { "machine_max_speed_x", "machine_max_speed_y", "machine_max_speed_z", "machine_max_speed_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", + "machine_max_junction_deviation", }; static std::vector s_Preset_printer_options { diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 6a035b1660..5138ebee9c 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1516,6 +1516,17 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* } } + // check junction deviation + const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0]; + if (warning_key.empty() && m_default_object_config.default_junction_deviation.value > max_junction_deviation) { + warning->string = L( "Junction deviation setting exceeds the printer's maximum value " + "(machine_max_junction_deviation).\nOrca will " + "automatically cap the junction deviation to ensure it doesn't surpass the printer's " + "capabilities.\nYou can adjust the " + "machine_max_junction_deviation value in your printer's configuration to get higher limits."); + warning->opt_key = warning_key; + } + // check acceleration const auto max_accel = m_config.machine_max_acceleration_extruding.values[0]; if (warning_key.empty() && m_default_object_config.default_acceleration > 0 && max_accel > 0) { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 3e07459566..a29a030b69 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2553,6 +2553,14 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); + def = this->add("default_junction_deviation", coFloat); + def->label = L("Junction Deviation"); + def->tooltip = L("Marlin Firmware Junction Deviation (replaces the traditional XY Jerk setting)"); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0)); + def = this->add("outer_wall_jerk", coFloat); def->label = L("Outer wall"); def->tooltip = L("Jerk of outer walls"); @@ -3437,6 +3445,15 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloats(axis.max_jerk)); } } + // M205 J... [mm] machine junction deviation limits + def = this->add("machine_max_junction_deviation", coFloats); + def->full_label = L("Maximum Junction Deviation"); + def->category = L("Machine limits"); + def->tooltip = L("Maximum junction deviation (M205 J, only apply if JD > 0 for Marlin Firmware)"); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloats{0. ,0. }); // M205 S... [mm/sec] def = this->add("machine_min_extruding_rate", coFloats); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index e874939c98..f99b560592 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -899,6 +899,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, initial_layer_jerk)) ((ConfigOptionFloat, travel_jerk)) ((ConfigOptionBool, precise_z_height)) + ((ConfigOptionFloat, default_junction_deviation)) ((ConfigOptionBool, interlocking_beam)) ((ConfigOptionFloat,interlocking_beam_width)) @@ -1070,6 +1071,8 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloats, machine_max_jerk_y)) ((ConfigOptionFloats, machine_max_jerk_z)) ((ConfigOptionFloats, machine_max_jerk_e)) + // M205 J... [mm] + ((ConfigOptionFloats, machine_max_junction_deviation)) // M205 T... [mm/sec] ((ConfigOptionFloats, machine_min_travel_rate)) // M205 S... [mm/sec] diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 359ad92766..6b05dfb909 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -563,6 +563,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co for (auto el : { "outer_wall_jerk", "inner_wall_jerk", "initial_layer_jerk", "top_surface_jerk", "travel_jerk", "infill_jerk"}) toggle_field(el, have_default_jerk); + toggle_line("default_junction_deviation", gcflavor == gcfMarlinFirmware); + bool have_skirt = config->opt_int("skirt_loops") > 0; toggle_field("skirt_height", have_skirt && config->opt_enum("draft_shield") != dsEnabled); toggle_line("single_loop_draft_shield", have_skirt); // ORCA: Display one wall if skirt enabled diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9c006fc5d1..e1cf0723a6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -10208,6 +10208,8 @@ void Plater::calib_input_shaping_freq(const Calib_Params& params) add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.stl" : "/calib/input_shaping/fast_tower_test.stl")); auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + printer_config->set_key_value("machine_max_junction_deviation", new ConfigOptionFloats {0.3}); filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 0.0 }); filament_config->set_key_value("slow_down_min_speed", new ConfigOptionFloats { 0.0 }); filament_config->set_key_value("slow_down_for_layer_cooling", new ConfigOptionBools{false}); @@ -10228,6 +10230,7 @@ void Plater::calib_input_shaping_freq(const Calib_Params& params) print_config->set_key_value("outer_wall_speed", new ConfigOptionFloat(200)); print_config->set_key_value("default_acceleration", new ConfigOptionFloat(2000)); print_config->set_key_value("outer_wall_acceleration", new ConfigOptionFloat(2000)); + print_config->set_key_value("default_junction_deviation", new ConfigOptionFloat(0.25)); model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); @@ -10252,6 +10255,8 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params) add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.stl" : "/calib/input_shaping/fast_tower_test.stl")); auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + printer_config->set_key_value("machine_max_junction_deviation", new ConfigOptionFloats{0.3}); filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 0.0 }); filament_config->set_key_value("slow_down_min_speed", new ConfigOptionFloats { 0.0 }); filament_config->set_key_value("slow_down_for_layer_cooling", new ConfigOptionBools{false}); @@ -10272,6 +10277,7 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params) print_config->set_key_value("outer_wall_speed", new ConfigOptionFloat(200)); print_config->set_key_value("default_acceleration", new ConfigOptionFloat(2000)); print_config->set_key_value("outer_wall_acceleration", new ConfigOptionFloat(2000)); + print_config->set_key_value("default_junction_deviation", new ConfigOptionFloat(0.25)); model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); @@ -10296,6 +10302,8 @@ void Plater::calib_junction_deviation(const Calib_Params& params) add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.stl" : "/calib/input_shaping/fast_tower_test.stl")); auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + printer_config->set_key_value("machine_max_junction_deviation", new ConfigOptionFloats{1.0}); filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 0.0 }); filament_config->set_key_value("slow_down_min_speed", new ConfigOptionFloats { 0.0 }); filament_config->set_key_value("slow_down_for_layer_cooling", new ConfigOptionBools{false}); @@ -10316,6 +10324,7 @@ void Plater::calib_junction_deviation(const Calib_Params& params) print_config->set_key_value("outer_wall_speed", new ConfigOptionFloat(200)); print_config->set_key_value("default_acceleration", new ConfigOptionFloat(2000)); print_config->set_key_value("outer_wall_acceleration", new ConfigOptionFloat(2000)); + print_config->set_key_value("default_junction_deviation", new ConfigOptionFloat(0.0)); model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index d58d7122aa..bcf8ccd3a8 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2198,6 +2198,7 @@ void TabPrint::build() optgroup->append_single_option_line("top_surface_jerk"); optgroup->append_single_option_line("initial_layer_jerk"); optgroup->append_single_option_line("travel_jerk"); + optgroup->append_single_option_line("default_junction_deviation"); optgroup = page->new_optgroup(L("Advanced"), L"param_advanced", 15); optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope", "extrusion-rate-smoothing"); @@ -4122,6 +4123,8 @@ PageShp TabPrinter::build_kinematics_page() append_option_line(optgroup, "machine_max_jerk_" + axis); } + // machine max junction deviation + append_option_line(optgroup, "machine_max_junction_deviation"); //optgroup = page->new_optgroup(L("Minimum feedrates")); // append_option_line(optgroup, "machine_min_extruding_rate"); // append_option_line(optgroup, "machine_min_travel_rate"); @@ -4634,6 +4637,9 @@ void TabPrinter::toggle_options() for (int i = 0; i < max_field; ++i) toggle_option("machine_max_acceleration_travel", gcf != gcfMarlinLegacy && gcf != gcfKlipper, i); toggle_line("machine_max_acceleration_travel", gcf != gcfMarlinLegacy && gcf != gcfKlipper); + for (int i = 0; i < max_field; ++i) + toggle_option("machine_max_junction_deviation", gcf == gcfMarlinFirmware, i); + toggle_line("machine_max_junction_deviation", gcf == gcfMarlinFirmware); } } diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index 3d30c97c42..6f7a1c0ddd 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -1159,7 +1159,6 @@ void Junction_Deviation_Test_Dlg::on_start(wxCommandEvent& event) { } else if (m_params.end > 0.3) { MessageDialog msg_dlg(nullptr, _L("NOTE: High values may cause Layer shift"), wxEmptyString, wxICON_WARNING | wxOK); msg_dlg.ShowModal(); - return; } m_params.mode = CalibMode::Calib_Junction_Deviation;