mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-17 14:02:35 +00:00
Merge upstream/main into belt/rebase/may-18
Reconciles the belt-printer branch with upstream PRs through #13723. Six files had conflicts; three additional files needed manual follow-up fixes where the auto-merge produced code that referenced upstream-renamed fields or changed function signatures. Notable reconciliations: - TreeSupport.cpp: kept belt-floor early-exit branches around HEAD's drop-down logic, folded upstream's `(distance_to_top > 0 ? 1 : 0)` formula into the non-belt-floor path (upstream PR #11812). Dropped dead `roof_enabled`/`force_tip_to_roof` locals. - TreeSupport3D.cpp: combined upstream's safety-offset + remove_small changes with HEAD's belt-floor clip in the per-slice trim loop. Dropped HEAD's `else` block (superseded by upstream's rewritten bottom-contact propagation) and re-added the belt-floor clip into the new propagation loop. Gated the propagation on belt printers to prevent OOM when belt-floor clipping produces empty initial slices. - TriangleSelector.{cpp,hpp}: merged both new `select_patch` parameters (HEAD's `up_direction` and upstream's `select_partially`); body uses `dot(up_direction)` for the overhang angle check and forwards `select_partially` to `select_triangle`. - SupportMaterial.cpp: `slicing_params.soluble_interface` → `zero_gap_interface_bottom` in HEAD's `detect_belt_floor_bottom_contacts`, matching upstream's same-purpose rename at line 2495. - Custom.json, GCodeWriter.cpp: simple additive merges (kept entries / includes from both sides). Verified by building OrcaSlicer (RelWithDebInfo) after a full deps rebuild (Eigen v5.0.1, libigl v2.6.0 are now managed deps) and slicing a scaled Benchy on the NORMALIZER belt-printer profile without OOM. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "GCodeWriter.hpp"
|
||||
#include "CustomGCode.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "PrintConfig.hpp"
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
@@ -298,6 +299,21 @@ std::string GCodeWriter::set_jerk_xy(double jerk)
|
||||
jerk = m_max_jerk_y;
|
||||
|
||||
gcode << "SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=" << jerk;
|
||||
|
||||
} else if (FLAVOR_IS(gcfRepetier)) {
|
||||
// Repetier uses M207 for temporary Jerk and combines X/Y into a single 'X' parameter.
|
||||
double jerk_xy = jerk;
|
||||
|
||||
// Clamp against the X machine limit
|
||||
if (m_max_jerk_x > 0 && jerk_xy > m_max_jerk_x)
|
||||
jerk_xy = m_max_jerk_x;
|
||||
|
||||
// Clamp against the Y machine limit as well to be safe
|
||||
if (m_max_jerk_y > 0 && jerk_xy > m_max_jerk_y)
|
||||
jerk_xy = m_max_jerk_y;
|
||||
|
||||
// Output the lowest safe limit using ONLY the X parameter
|
||||
gcode << "M207 X" << jerk_xy;
|
||||
} else {
|
||||
double jerk_x = jerk;
|
||||
double jerk_y = jerk;
|
||||
@@ -309,7 +325,7 @@ std::string GCodeWriter::set_jerk_xy(double jerk)
|
||||
|
||||
gcode << "M205 X" << jerk_x << " Y" << jerk_y;
|
||||
}
|
||||
|
||||
//the is_bbl check should be in the else statement above so that it doesn't inadverently added Z & E to klipper
|
||||
if (m_is_bbl_printers)
|
||||
gcode << std::setprecision(2) << " Z" << m_max_jerk_z << " E" << m_max_jerk_e;
|
||||
|
||||
@@ -324,7 +340,7 @@ std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double je
|
||||
{
|
||||
// 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");
|
||||
throw std::runtime_error(_u8L("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)
|
||||
@@ -366,7 +382,7 @@ 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(gcfMarlinFirmware) && junction_deviation > 0 && m_max_junction_deviation > 0) {
|
||||
if (FLAVOR_IS(gcfMarlinFirmware) && m_max_junction_deviation > 0 && junction_deviation > 0) {
|
||||
// Clamp the junction deviation to the allowed maximum.
|
||||
gcode << "M205 J";
|
||||
if (junction_deviation <= m_max_junction_deviation) {
|
||||
@@ -396,74 +412,98 @@ std::string GCodeWriter::set_pressure_advance(double pa) const
|
||||
gcode << "SET_PRESSURE_ADVANCE ADVANCE=" << std::setprecision(4) << pa << "; Override pressure advance value\n";
|
||||
else if(FLAVOR_IS(gcfRepRapFirmware))
|
||||
gcode << ("M572 D0 S") << std::setprecision(4) << pa << "; Override pressure advance value\n";
|
||||
else if (FLAVOR_IS(gcfRepetier))
|
||||
// Repetier M233: X is quadratic (K), Y is linear (L).
|
||||
// Applying the value to both parameters simultaneously.
|
||||
gcode << "M233 X" << std::setprecision(4) << pa << " Y" << std::setprecision(4) << pa << " ; Override pressure advance value\n";
|
||||
else
|
||||
gcode << "M900 K" <<std::setprecision(4)<< pa << "; Override pressure advance value\n";
|
||||
}
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
// Orca: input shaping support
|
||||
std::string GCodeWriter::set_input_shaping(char axis, float damp, float freq, std::string type) const
|
||||
{
|
||||
if (FLAVOR_IS(gcfMarlinLegacy))
|
||||
throw std::runtime_error("Input shaping is not supported by Marlin < 2.1.2.\nCheck your firmware version and update your G-code flavor to ´Marlin 2´");
|
||||
if (freq < 0.0f || damp < 0.f || damp > 1.0f || (axis != 'X' && axis != 'Y' && axis != 'Z' && axis != 'A'))// A = all axis
|
||||
{
|
||||
throw std::runtime_error("Invalid input shaping parameters: freq=" + std::to_string(freq) + ", damp=" + std::to_string(damp));
|
||||
bool disable = type == "Disable";
|
||||
if (disable){
|
||||
freq = 0.0f;
|
||||
damp = 0.0f;
|
||||
axis = 'A';
|
||||
type = "Default";
|
||||
} else if (freq < 0.0f || damp < 0.f || damp > 1.0f || (axis != 'X' && axis != 'Y' && axis != 'Z' && axis != 'A')) { // A = all axis
|
||||
throw std::runtime_error("Invalid input shaping parameters: axis=" + std::string(1, axis) + ", freq=" + std::to_string(freq) + ", damp=" + std::to_string(damp));
|
||||
}
|
||||
std::ostringstream gcode;
|
||||
if (FLAVOR_IS(gcfKlipper)) {
|
||||
gcode << "SET_INPUT_SHAPER";
|
||||
std::ostringstream params;
|
||||
switch (this->config.gcode_flavor) {
|
||||
case gcfKlipper: {
|
||||
if (!type.empty() && type != "Default") {
|
||||
gcode << " SHAPER_TYPE=" << type;
|
||||
params << " SHAPER_TYPE=" << type;
|
||||
}
|
||||
if (axis != 'A')
|
||||
{
|
||||
if (freq > 0.0f) {
|
||||
gcode << " SHAPER_FREQ_" << axis << "=" << std::fixed << std::setprecision(2) << freq;
|
||||
}
|
||||
if (damp > 0.0f){
|
||||
gcode << " DAMPING_RATIO_" << axis << "=" << std::fixed << std::setprecision(3) << damp;
|
||||
}
|
||||
} else {
|
||||
if (freq > 0.0f) {
|
||||
gcode << " SHAPER_FREQ_X=" << std::fixed << std::setprecision(2) << freq << " SHAPER_FREQ_Y=" << std::fixed << std::setprecision(2) << freq;
|
||||
params << " SHAPER_FREQ_" << axis << "=" << std::fixed << std::setprecision(2) << freq;
|
||||
}
|
||||
if (damp > 0.0f) {
|
||||
gcode << " DAMPING_RATIO_X=" << std::fixed << std::setprecision(3) << damp << " DAMPING_RATIO_Y=" << std::fixed << std::setprecision(3) << damp;
|
||||
params << " DAMPING_RATIO_" << axis << "=" << std::fixed << std::setprecision(3) << damp;
|
||||
}
|
||||
} else {
|
||||
if (freq > 0.0f || disable) {
|
||||
params << " SHAPER_FREQ_X=" << std::fixed << std::setprecision(2) << freq << " SHAPER_FREQ_Y=" << std::fixed << std::setprecision(2) << freq;
|
||||
}
|
||||
if (damp > 0.0f || disable) {
|
||||
params << " DAMPING_RATIO_X=" << std::fixed << std::setprecision(3) << damp << " DAMPING_RATIO_Y=" << std::fixed << std::setprecision(3) << damp;
|
||||
}
|
||||
}
|
||||
} else if (FLAVOR_IS(gcfRepRapFirmware)) {
|
||||
gcode << "M593";
|
||||
if (!params.str().empty()) {
|
||||
gcode << "SET_INPUT_SHAPER" << params.str();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gcfRepRapFirmware: {
|
||||
if (!type.empty() && type != "Default" && type != "DAA") {
|
||||
gcode << " P\"" << type << "\"";
|
||||
params << " P\"" << type << "\"";
|
||||
}
|
||||
if (freq > 0.0f) {
|
||||
gcode << " F" << std::fixed << std::setprecision(2) << freq;
|
||||
if (freq > 0.0f || disable) {
|
||||
params << " F" << std::fixed << std::setprecision(2) << freq;
|
||||
}
|
||||
if (damp > 0.0f){
|
||||
gcode << " S" << std::fixed << std::setprecision(3) << damp;
|
||||
if (damp > 0.0f || disable) {
|
||||
params << " S" << std::fixed << std::setprecision(3) << damp;
|
||||
}
|
||||
} else if (FLAVOR_IS(gcfMarlinFirmware)) {
|
||||
gcode << "M593";
|
||||
if (axis != 'A')
|
||||
{
|
||||
gcode << " " << axis;
|
||||
if (!params.str().empty()) {
|
||||
gcode << "M593" << params.str();
|
||||
}
|
||||
if (freq > 0.0f)
|
||||
{
|
||||
gcode << " F" << std::fixed << std::setprecision(2) << freq;
|
||||
}
|
||||
if (damp > 0.0f)
|
||||
{
|
||||
gcode << " D" << std::fixed << std::setprecision(3) << damp;
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("Input shaping is only supported by Klipper, RepRapFirmware and Marlin 2");
|
||||
break;
|
||||
}
|
||||
if (GCodeWriter::full_gcode_comment){
|
||||
gcode << " ; Override input shaping";
|
||||
case gcfMarlinFirmware: {
|
||||
if (axis != 'A') {
|
||||
params << " " << axis;
|
||||
}
|
||||
if (freq > 0.0f || disable) {
|
||||
params << " F" << std::fixed << std::setprecision(2) << freq;
|
||||
}
|
||||
if (damp > 0.0f || disable) {
|
||||
params << " D" << std::fixed << std::setprecision(3) << damp;
|
||||
}
|
||||
if (!params.str().empty()) {
|
||||
gcode << "M593" << params.str();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gcfMarlinLegacy: {
|
||||
throw std::runtime_error(_u8L("Input shaping is not supported by Marlin < 2.1.2.\nCheck your firmware version and update your G-code flavor to ´Marlin 2´"));
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error(_u8L("Input shaping is only supported by Klipper, RepRapFirmware and Marlin 2"));
|
||||
}
|
||||
if (!gcode.str().empty()) {
|
||||
if (GCodeWriter::full_gcode_comment) {
|
||||
gcode << " ; Override input shaping";
|
||||
}
|
||||
gcode << "\n";
|
||||
}
|
||||
gcode << "\n";
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user