diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml index b6b939d81b..0fd5724f9e 100644 --- a/.github/workflows/build_orca.yml +++ b/.github/workflows/build_orca.yml @@ -155,6 +155,7 @@ jobs: - name: Install nsis if: matrix.os == 'windows-latest' run: | + dir "C:/Program Files (x86)/Windows Kits/10/Include" choco install nsis - name: download deps diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 53731324ce..3a99b517ff 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3457,6 +3457,7 @@ LayerResult GCode::process_layer( //BBS if (first_layer) { + // Orca: we don't need to optimize the Klipper as only set once if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) { gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.initial_layer_acceleration.value + 0.5)); } @@ -3483,9 +3484,10 @@ LayerResult GCode::process_layer( gcode += this->unretract(); } } - // BBS: reset acceleration at sencond layer + // Reset acceleration at sencond layer + // Orca: only set once, don't need to call set_accel_and_jerk if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) { - gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5)); + gcode += m_writer.set_print_acceleration((unsigned int) floor(m_config.default_acceleration.value + 0.5)); } if (m_config.default_jerk.value > 0 && m_config.initial_layer_jerk.value > 0) { @@ -4501,6 +4503,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // compensate retraction gcode += this->unretract(); m_config.apply(m_calib_config); + + // Orca: optimize for Klipper, set acceleration and jerk in one command + unsigned int acceleration_i = 0; + double jerk = 0; // adjust acceleration if (m_config.default_acceleration.value > 0) { double acceleration; @@ -4525,12 +4531,11 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } else { acceleration = m_config.default_acceleration.value; } - gcode += m_writer.set_print_acceleration((unsigned int)floor(acceleration + 0.5)); + acceleration_i = (unsigned int)floor(acceleration + 0.5); } // adjust X Y jerk if (m_config.default_jerk.value > 0) { - double jerk; if (this->on_first_layer() && m_config.initial_layer_jerk.value > 0) { jerk = m_config.initial_layer_jerk.value; } else if (m_config.outer_wall_jerk.value > 0 && is_external_perimeter(path.role())) { @@ -4545,6 +4550,13 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, else { jerk = m_config.default_jerk.value; } + } + + if (m_writer.get_gcode_flavor() == gcfKlipper) { + gcode += m_writer.set_accel_and_jerk(acceleration_i, jerk); + + } else { + gcode += m_writer.set_print_acceleration(acceleration_i); gcode += m_writer.set_jerk_xy(jerk); } @@ -5017,23 +5029,31 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string const bool used_external_mp_once = m_avoid_crossing_perimeters.used_external_mp_once(); std::string gcode; - // SoftFever + // Orca: we don't need to optimize the Klipper as only set once + double jerk_to_set = 0.0; + unsigned int acceleration_to_set = 0; if (this->on_first_layer()) { if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) { - gcode += m_writer.set_travel_acceleration((unsigned int)floor(m_config.initial_layer_acceleration.value + 0.5)); + acceleration_to_set = (unsigned int) floor(m_config.initial_layer_acceleration.value + 0.5); } if (m_config.default_jerk.value > 0 && m_config.initial_layer_jerk.value > 0) { - gcode += m_writer.set_jerk_xy(m_config.initial_layer_jerk.value); + jerk_to_set = m_config.initial_layer_jerk.value; } } else { if (m_config.default_acceleration.value > 0 && m_config.travel_acceleration.value > 0) { - gcode += m_writer.set_travel_acceleration((unsigned int)floor(m_config.travel_acceleration.value + 0.5)); + acceleration_to_set = (unsigned int) floor(m_config.travel_acceleration.value + 0.5); } - if (m_config.default_jerk.value > 0 && m_config.travel_jerk.value > 0) { - gcode += m_writer.set_jerk_xy(m_config.travel_jerk.value); + jerk_to_set = m_config.travel_jerk.value; } } + if (m_writer.get_gcode_flavor() == gcfKlipper) { + gcode += m_writer.set_accel_and_jerk(acceleration_to_set, jerk_to_set); + } else { + gcode += m_writer.set_travel_acceleration(acceleration_to_set); + gcode += m_writer.set_jerk_xy(jerk_to_set); + } + // if a retraction would be needed, try to use reduce_crossing_wall to plan a // multi-hop travel path inside the configuration space if (needs_retraction diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 1e4ae800d1..e5113a48e1 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -248,6 +248,48 @@ std::string GCodeWriter::set_jerk_xy(double jerk) } +std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double jerk) +{ + // Only Klipper supports setting acceleration and jerk at the same time. Throw an error if we try to do this on other flavours. + if(FLAVOR_IS_NOT(gcfKlipper)) + throw std::runtime_error("set_accel_and_jerk() is only supported by Klipper"); + + // Clamp the acceleration to the allowed maximum. + if (m_max_acceleration > 0 && acceleration > m_max_acceleration) + acceleration = m_max_acceleration; + + bool is_empty = true; + std::ostringstream gcode; + gcode << "SET_VELOCITY_LIMIT"; + if (acceleration != 0 && acceleration != m_last_acceleration) { + gcode << " ACCEL=" << acceleration; + if (this->config.accel_to_decel_enable) { + gcode << " ACCEL_TO_DECEL=" << acceleration * this->config.accel_to_decel_factor / 100; + } + m_last_acceleration = acceleration; + is_empty = false; + } + // Clamp the jerk to the allowed maximum. + if (m_max_jerk > 0 && jerk > m_max_jerk) + jerk = m_max_jerk; + + if (jerk > 0.01 && !is_approx(jerk, m_last_jerk)) { + gcode << " SQUARE_CORNER_VELOCITY=" << jerk; + m_last_jerk = jerk; + is_empty = false; + } + + if(is_empty) + return std::string(); + + if (GCodeWriter::full_gcode_comment) + gcode << " ; adjust VELOCITY_LIMIT(accel/jerk)"; + gcode << "\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 18620881b2..1a26abac5f 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -49,6 +49,8 @@ public: std::string set_print_acceleration(unsigned int acceleration) { return set_acceleration_internal(Acceleration::Print, acceleration); } std::string set_travel_acceleration(unsigned int acceleration) { return set_acceleration_internal(Acceleration::Travel, acceleration); } std::string set_jerk_xy(double jerk); + // Orca: set acceleration and jerk in one command for Klipper + std::string set_accel_and_jerk(unsigned int acceleration, double jerk); std::string set_pressure_advance(double pa) const; std::string reset_e(bool force = false); std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const; @@ -112,6 +114,7 @@ public: void set_is_bbl_machine(bool bval) {m_is_bbl_printers = bval;} const bool is_bbl_printers() const {return m_is_bbl_printers;} void set_is_first_layer(bool bval) { m_is_first_layer = bval; } + GCodeFlavor get_gcode_flavor() const { return config.gcode_flavor; } private: // Extruders are sorted by their ID, so that binary search is possible.