diff --git a/.gitattributes b/.gitattributes index e69de29bb2..4cab1f4d26 100644 --- a/.gitattributes +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 92230a48ed..417ebf9da3 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5404,12 +5404,37 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, //} if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) { // cap speed with max_volumetric_speed anyway (even if user is not using autospeed) - speed = std::min( - speed, - EXTRUDER_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm - ); + speed = std::min(speed, EXTRUDER_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm); } + // ORCA: resonance‑avoidance on short external perimeters +{ + double ref_speed = speed; // stash the pre‑cap speed + if (path.role() == erExternalPerimeter + && m_config.resonance_avoidance.value) { + // if our original speed was above “max”, disable RA for this loop + if (ref_speed > m_config.max_resonance_avoidance_speed.value) { + m_resonance_avoidance = false; + } + + // re‑apply volumetric cap + if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) { + speed = std::min( + speed, + EXTRUDER_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm + ); + } + + // if still in avoidance mode and under “max”, clamp to “min” + if (m_resonance_avoidance + && speed <= m_config.max_resonance_avoidance_speed.value) { + speed = std::min(speed, m_config.min_resonance_avoidance_speed.value); + } + + // reset flag for next segment + m_resonance_avoidance = true; + } +} bool variable_speed = false; std::vector new_points {}; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 749d929dd6..46f6cbde88 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -165,6 +165,7 @@ public: GCode() : m_origin(Vec2d::Zero()), m_enable_loop_clipping(true), + m_resonance_avoidance(true), m_enable_cooling_markers(false), m_enable_extrusion_role_markers(false), m_last_processor_extrusion_role(erNone), @@ -506,6 +507,8 @@ private: AvoidCrossingPerimeters m_avoid_crossing_perimeters; RetractWhenCrossingPerimeters m_retract_when_crossing_perimeters; bool m_enable_loop_clipping; + //resonance avoidance + bool m_resonance_avoidance; // If enabled, the G-code generator will put following comments at the ends // of the G-code lines: _EXTRUDE_SET_SPEED, _WIPE, _OVERHANG_FAN_START, _OVERHANG_FAN_END // Those comments are received and consumed (removed from the G-code) by the CoolingBuffer.pm Perl module. diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index f1c0cf244f..2b9119ad5c 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -837,7 +837,7 @@ static std::vector s_Preset_print_options { "hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth", "small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model", "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "scarf_joint_flow_ratio", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", "scarf_overhang_threshold", - "interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width","calib_flowrate_topinfill_special_order" + "interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width","calib_flowrate_topinfill_special_order", }; static std::vector s_Preset_filament_options { @@ -878,6 +878,8 @@ static std::vector s_Preset_machine_limits_options { "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", + //resonance avoidance ported from qidi slicer + "resonance_avoidance", "min_resonance_avoidance_speed", "max_resonance_avoidance_speed", }; static std::vector s_Preset_printer_options { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 6528034fbc..650018208b 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3554,6 +3554,31 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats{ 0., 0. }); + // resonance avoidance ported over from qidi slicer + def = this->add("resonance_avoidance", coBool); + def->label = L("Resonance avoidance"); + def->tooltip = L("By reducing the speed of the outer wall to avoid the resonance zone of the printer, ringing on the surface of the " + "model are avoided.\n" + "Please turn this option off when testing ringing."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("min_resonance_avoidance_speed", coFloat); + def->label = L("Min"); + def->tooltip = L("Minimum speed of resonance avoidance."); + def->sidetext = L("mm/s"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(70)); + + def = this->add("max_resonance_avoidance_speed", coFloat); + def->label = L("Max"); + def->tooltip = L("Maximum speed of resonance avoidance."); + def->sidetext = L("mm/s"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(120)); + def = this->add("fan_max_speed", coFloats); def->label = L("Fan speed"); def->tooltip = L("Part cooling fan speed may be increased when auto cooling is enabled. " diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 81e2884f7b..fade4a9e3f 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1049,8 +1049,6 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloatOrPercent, scarf_joint_speed)) ((ConfigOptionFloat, scarf_joint_flow_ratio)) ((ConfigOptionPercent, scarf_overhang_threshold)) - - ) PRINT_CONFIG_CLASS_DEFINE( @@ -1085,6 +1083,11 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloats, machine_min_travel_rate)) // M205 S... [mm/sec] ((ConfigOptionFloats, machine_min_extruding_rate)) + + //resonance avoidance ported from qidi slicer + ((ConfigOptionBool, resonance_avoidance)) + ((ConfigOptionFloat, min_resonance_avoidance_speed)) + ((ConfigOptionFloat, max_resonance_avoidance_speed)) ) // This object is mapped to Perl as Slic3r::Config::GCode. diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index a486fbefc0..3ba87e3c40 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2206,6 +2206,7 @@ void TabPrint::build() optgroup->append_single_option_line("support_interface_speed"); optgroup = page->new_optgroup(L("Overhang speed"), L"param_overhang_speed", 15); optgroup->append_single_option_line("enable_overhang_speed", "slow-down-for-overhang"); + // Orca: DEPRECATED // optgroup->append_single_option_line("overhang_speed_classic", "slow-down-for-overhang"); optgroup->append_single_option_line("slowdown_for_curled_perimeters"); @@ -4166,6 +4167,17 @@ PageShp TabPrinter::build_kinematics_page() } auto optgroup = page->new_optgroup(L("Advanced"), "param_advanced"); optgroup->append_single_option_line("emit_machine_limits_to_gcode"); + + // resonance avoidance ported over from qidi slicer + optgroup = page->new_optgroup(L("Resonance Avoidance")); + optgroup->append_single_option_line("resonance_avoidance"); + // Resonance‑avoidance speed inputs + { + Line resonance_line = {L("Resonance Avoidance Speed"), L("")}; + resonance_line.append_option(optgroup->get_option("min_resonance_avoidance_speed")); + resonance_line.append_option(optgroup->get_option("max_resonance_avoidance_speed")); + optgroup->append_line(resonance_line); + } const std::vector speed_axes{ "machine_max_speed_x", @@ -4708,6 +4720,10 @@ void TabPrinter::toggle_options() 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); + + bool resonance_avoidance = m_config->opt_bool("resonance_avoidance"); + toggle_option("min_resonance_avoidance_speed", resonance_avoidance); + toggle_option("max_resonance_avoidance_speed", resonance_avoidance); } }