Merge remote-tracking branch 'upstream/main' into dev/h2d-2

This commit is contained in:
Noisyfox
2025-10-20 09:37:23 +08:00
60 changed files with 460 additions and 221 deletions

View File

@@ -1462,43 +1462,31 @@ void Layer::make_ironing()
double height;
double speed;
double angle;
bool is_using_template_angle;
double inset;
bool operator<(const IroningParams &rhs) const {
if (this->extruder < rhs.extruder)
return true;
if (this->extruder > rhs.extruder)
return false;
if (int(this->just_infill) < int(rhs.just_infill))
return true;
if (int(this->just_infill) > int(rhs.just_infill))
return false;
if (this->line_spacing < rhs.line_spacing)
return true;
if (this->line_spacing > rhs.line_spacing)
return false;
if (this->height < rhs.height)
return true;
if (this->height > rhs.height)
return false;
if (this->speed < rhs.speed)
return true;
if (this->speed > rhs.speed)
return false;
if (this->angle < rhs.angle)
return true;
if (this->angle > rhs.angle)
return false;
if (this->inset < rhs.inset)
return true;
if (this->inset > rhs.inset)
return false;
RETURN_COMPARE_NON_EQUAL(extruder);
RETURN_COMPARE_NON_EQUAL(just_infill);
RETURN_COMPARE_NON_EQUAL(line_spacing);
RETURN_COMPARE_NON_EQUAL(height);
RETURN_COMPARE_NON_EQUAL(speed);
RETURN_COMPARE_NON_EQUAL(angle);
RETURN_COMPARE_NON_EQUAL(is_using_template_angle);
RETURN_COMPARE_NON_EQUAL(inset);
return false;
}
bool operator==(const IroningParams &rhs) const {
return this->extruder == rhs.extruder && this->just_infill == rhs.just_infill &&
this->line_spacing == rhs.line_spacing && this->height == rhs.height && this->speed == rhs.speed && this->angle == rhs.angle && this->pattern == rhs.pattern && this->inset == rhs.inset;
return this->extruder == rhs.extruder &&
this->just_infill == rhs.just_infill &&
this->line_spacing == rhs.line_spacing &&
this->height == rhs.height &&
this->speed == rhs.speed &&
this->angle == rhs.angle &&
this->is_using_template_angle == rhs.is_using_template_angle &&
this->pattern == rhs.pattern &&
this->inset == rhs.inset;
}
LayerRegion *layerm = nullptr;
@@ -1545,7 +1533,8 @@ void Layer::make_ironing()
ironing_params.inset = config.ironing_inset;
ironing_params.height = default_layer_height * 0.01 * config.ironing_flow;
ironing_params.speed = config.ironing_speed;
ironing_params.angle = (config.ironing_angle >= 0 ? config.ironing_angle : config.infill_direction) * M_PI / 180.;
ironing_params.angle = calculate_infill_rotation_angle(this->object(), this->id(), config.solid_infill_direction.value, config.solid_infill_rotate_template.value) + config.ironing_angle * M_PI / 180.;
ironing_params.is_using_template_angle = !config.solid_infill_rotate_template.value.empty();
ironing_params.pattern = config.ironing_pattern;
ironing_params.layerm = layerm;
by_extruder.emplace_back(ironing_params);
@@ -1641,6 +1630,7 @@ void Layer::make_ironing()
// Create the filler object.
f->spacing = ironing_params.line_spacing;
f->angle = float(ironing_params.angle);
f->is_using_template_angle = ironing_params.is_using_template_angle;
f->link_max_length = (coord_t) scale_(3. * f->spacing);
double extrusion_height = ironing_params.height * f->spacing / nozzle_dmr;
float extrusion_width = Flow::rounded_rectangle_extrusion_width_from_spacing(float(nozzle_dmr), float(extrusion_height));

View File

@@ -4234,23 +4234,31 @@ LayerResult GCode::process_layer(
}
case CalibMode::Calib_Input_shaping_freq: {
if (m_layer_index == 1){
gcode += writer().set_input_shaping('A', print.calib_params().start, 0.f);
gcode += writer().set_input_shaping('A', print.calib_params().start, 0.f, print.calib_params().shaper_type);
if (m_writer.get_gcode_flavor() == gcfKlipper) {
// Disable minimum cruise ratio to ensure consistent motion for calibration
gcode += "SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=0\n";
}
} else {
if (print.calib_params().freqStartX == print.calib_params().freqStartY && print.calib_params().freqEndX == print.calib_params().freqEndY) {
gcode += writer().set_input_shaping('A', 0.f, (print.calib_params().freqStartX) + ((print.calib_params().freqEndX)-(print.calib_params().freqStartX)) * (m_layer_index - 2) / (m_layer_count - 3));
gcode += writer().set_input_shaping('A', 0.f, (print.calib_params().freqStartX) + ((print.calib_params().freqEndX)-(print.calib_params().freqStartX)) * (m_layer_index - 2) / (m_layer_count - 3), "");
} else {
gcode += writer().set_input_shaping('X', 0.f, (print.calib_params().freqStartX) + ((print.calib_params().freqEndX)-(print.calib_params().freqStartX)) * (m_layer_index - 2) / (m_layer_count - 3));
gcode += writer().set_input_shaping('Y', 0.f, (print.calib_params().freqStartY) + ((print.calib_params().freqEndY)-(print.calib_params().freqStartY)) * (m_layer_index - 2) / (m_layer_count - 3));
gcode += writer().set_input_shaping('X', 0.f, (print.calib_params().freqStartX) + ((print.calib_params().freqEndX)-(print.calib_params().freqStartX)) * (m_layer_index - 2) / (m_layer_count - 3), "");
gcode += writer().set_input_shaping('Y', 0.f, (print.calib_params().freqStartY) + ((print.calib_params().freqEndY)-(print.calib_params().freqStartY)) * (m_layer_index - 2) / (m_layer_count - 3), "");
}
}
break;
}
case CalibMode::Calib_Input_shaping_damp: {
if (m_layer_index == 1){
gcode += writer().set_input_shaping('X', 0.f, print.calib_params().freqStartX);
gcode += writer().set_input_shaping('Y', 0.f, print.calib_params().freqStartY);
if (m_writer.get_gcode_flavor() == gcfKlipper) {
// Disable minimum cruise ratio to ensure consistent motion for calibration
gcode += "SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=0\n";
}
gcode += writer().set_input_shaping('X', 0.f, print.calib_params().freqStartX, print.calib_params().shaper_type);
gcode += writer().set_input_shaping('Y', 0.f, print.calib_params().freqStartY, print.calib_params().shaper_type);
} else {
gcode += writer().set_input_shaping('A', print.calib_params().start + ((print.calib_params().end)-(print.calib_params().start)) * (m_layer_index) / (m_layer_count), 0.f);
gcode += writer().set_input_shaping('A', print.calib_params().start + ((print.calib_params().end)-(print.calib_params().start)) * (m_layer_index) / (m_layer_count), 0.f, "");
}
break;
}

View File

@@ -351,8 +351,10 @@ std::string GCodeWriter::set_pressure_advance(double pa) const
return gcode.str();
}
std::string GCodeWriter::set_input_shaping(char axis, float damp, float freq) const
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));
@@ -360,14 +362,17 @@ std::string GCodeWriter::set_input_shaping(char axis, float damp, float freq) co
std::ostringstream gcode;
if (FLAVOR_IS(gcfKlipper)) {
gcode << "SET_INPUT_SHAPER";
if (!type.empty() && type != "Default") {
gcode << " 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 << "=" << damp;
}
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;
@@ -376,7 +381,18 @@ std::string GCodeWriter::set_input_shaping(char axis, float damp, float freq) co
gcode << " DAMPING_RATIO_X=" << std::fixed << std::setprecision(3) << damp << " DAMPING_RATIO_Y=" << std::fixed << std::setprecision(3) << damp;
}
}
} else {
} else if (FLAVOR_IS(gcfRepRapFirmware)) {
gcode << "M593";
if (!type.empty() && type != "Default" && type != "DAA") {
gcode << " P\"" << type << "\"";
}
if (freq > 0.0f) {
gcode << " F" << std::fixed << std::setprecision(2) << freq;
}
if (damp > 0.0f){
gcode << " S" << std::fixed << std::setprecision(3) << damp;
}
} else if (FLAVOR_IS(gcfMarlinFirmware)) {
gcode << "M593";
if (axis != 'A')
{
@@ -390,6 +406,8 @@ std::string GCodeWriter::set_input_shaping(char axis, float damp, float freq) co
{
gcode << " D" << std::fixed << std::setprecision(3) << damp;
}
} else {
throw std::runtime_error("Input shaping is only supported by Klipper, RepRapFirmware and Marlin 2");
}
if (GCodeWriter::full_gcode_comment){
gcode << " ; Override input shaping";

View File

@@ -58,7 +58,7 @@ public:
std::string set_accel_and_jerk(unsigned int acceleration, double jerk);
std::string set_junction_deviation(double junction_deviation);
std::string set_pressure_advance(double pa) const;
std::string set_input_shaping(char axis, float damp, float freq) const;
std::string set_input_shaping(char axis, float damp, float freq, std::string type) const;
std::string reset_e(bool force = false);
std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const;
// return false if this extruder was already selected

View File

@@ -3780,14 +3780,14 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloat(20));
def = this->add("ironing_angle", coFloat);
def->label = L("Ironing angle");
def->label = L("Ironing angle offset");
def->category = L("Quality");
def->tooltip = L("The angle ironing is done at. A negative number disables this function and uses the default method.");
def->tooltip = L("The angle of ironing lines offset from the top surface.");
def->sidetext = u8"°"; // degrees, don't need translation
def->min = -1;
def->min = 0;
def->max = 359;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(-1));
def->set_default_value(new ConfigOptionFloat(0));
def = this->add("layer_change_gcode", coString);
def->label = L("Layer change G-code");
@@ -7290,6 +7290,8 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
opt_key = "bottom_solid_infill_flow_ratio";
} else if (opt_key == "ironing_direction") {
opt_key = "ironing_angle";
} else if (opt_key == "ironing_angle" && boost::starts_with(value, "-")) {
value = "0";
} else if (opt_key == "counterbole_hole_bridging") {
opt_key = "counterbore_hole_bridging";
} else if (opt_key == "draft_shield" && value == "limited") {

View File

@@ -39,6 +39,7 @@ struct Calib_Params
bool print_numbers;
double freqStartX, freqEndX, freqStartY, freqEndY;
int test_model;
std::string shaper_type;
std::vector<double> accelerations;
std::vector<double> speeds;

View File

@@ -12303,7 +12303,28 @@ void Plater::calib_input_shaping_freq(const Calib_Params& params)
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});
const auto gcode_flavor_option = printer_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor");
float junction_deviation_value = 0.f;
if (gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfMarlinFirmware) {
const auto machine_junction_option = printer_config->option<ConfigOptionFloats>("machine_max_junction_deviation");
const float current = (machine_junction_option && !machine_junction_option->values.empty())
? machine_junction_option->values.front()
: 0.f;
junction_deviation_value = std::max(current, 0.25f);
}
float machine_max_jerk_x = 0.f;
if (const auto option = printer_config->option<ConfigOptionFloats>("machine_max_jerk_x");
option != nullptr && !option->values.empty()) {
machine_max_jerk_x = option->values.front();
}
float machine_max_jerk_y = 0.f;
if (const auto option = printer_config->option<ConfigOptionFloats>("machine_max_jerk_y");
option != nullptr && !option->values.empty()) {
machine_max_jerk_y = option->values.front();
}
const float jerk_value = std::max((gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfKlipper) ? 5.f : 10.f,
std::min(machine_max_jerk_x, machine_max_jerk_y));
printer_config->set_key_value("machine_max_junction_deviation", new ConfigOptionFloats {junction_deviation_value});
printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
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 });
@@ -12323,9 +12344,11 @@ void Plater::calib_input_shaping_freq(const Calib_Params& params)
print_config->set_key_value("spiral_mode_smooth", new ConfigOptionBool(false));
print_config->set_key_value("bottom_surface_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
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));
print_config->set_key_value("default_acceleration", new ConfigOptionFloat(20000));
print_config->set_key_value("outer_wall_acceleration", new ConfigOptionFloat(20000));
print_config->set_key_value("default_jerk", new ConfigOptionFloat(jerk_value));
print_config->set_key_value("outer_wall_jerk", new ConfigOptionFloat(jerk_value));
print_config->set_key_value("default_junction_deviation", new ConfigOptionFloat(junction_deviation_value));
model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(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));
@@ -12351,7 +12374,28 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params)
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});
const auto gcode_flavor_option = printer_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor");
float junction_deviation_value = 0.f;
if (gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfMarlinFirmware) {
const auto machine_junction_option = printer_config->option<ConfigOptionFloats>("machine_max_junction_deviation");
const float current = (machine_junction_option && !machine_junction_option->values.empty())
? machine_junction_option->values.front()
: 0.f;
junction_deviation_value = std::max(current, 0.25f);
}
float machine_max_jerk_x = 0.f;
if (const auto option = printer_config->option<ConfigOptionFloats>("machine_max_jerk_x");
option != nullptr && !option->values.empty()) {
machine_max_jerk_x = option->values.front();
}
float machine_max_jerk_y = 0.f;
if (const auto option = printer_config->option<ConfigOptionFloats>("machine_max_jerk_y");
option != nullptr && !option->values.empty()) {
machine_max_jerk_y = option->values.front();
}
const float jerk_value = std::max((gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfKlipper) ? 5.f : 10.f,
std::min(machine_max_jerk_x, machine_max_jerk_y));
printer_config->set_key_value("machine_max_junction_deviation", new ConfigOptionFloats{junction_deviation_value});
printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
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 });
@@ -12371,9 +12415,11 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params)
print_config->set_key_value("spiral_mode_smooth", new ConfigOptionBool(false));
print_config->set_key_value("bottom_surface_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
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));
print_config->set_key_value("default_acceleration", new ConfigOptionFloat(20000));
print_config->set_key_value("outer_wall_acceleration", new ConfigOptionFloat(20000));
print_config->set_key_value("default_jerk", new ConfigOptionFloat(jerk_value));
print_config->set_key_value("outer_wall_jerk", new ConfigOptionFloat(jerk_value));
print_config->set_key_value("default_junction_deviation", new ConfigOptionFloat(junction_deviation_value));
model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(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));
@@ -12422,6 +12468,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_jerk", new ConfigOptionFloat(0));
print_config->set_key_value("default_junction_deviation", new ConfigOptionFloat(0.0));
model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0));

View File

@@ -2333,7 +2333,7 @@ void TabPrint::build()
optgroup->append_single_option_line("ironing_flow", "quality_settings_ironing#flow");
optgroup->append_single_option_line("ironing_spacing", "quality_settings_ironing#line-spacing");
optgroup->append_single_option_line("ironing_inset", "quality_settings_ironing#inset");
optgroup->append_single_option_line("ironing_angle", "quality_settings_ironing#angle");
optgroup->append_single_option_line("ironing_angle", "quality_settings_ironing#angle-offset");
optgroup = page->new_optgroup(L("Wall generator"), L"param_wall_generator");
optgroup->append_single_option_line("wall_generator", "quality_settings_wall_generator");

View File

@@ -6,6 +6,8 @@
#include "MainFrame.hpp"
#include "Widgets/DialogButtons.hpp"
#include <string>
#include <vector>
#include "libslic3r/PrintConfig.hpp"
namespace Slic3r { namespace GUI {
@@ -28,6 +30,39 @@ int GetTextMax(wxWindow* parent, const std::vector<wxString>& labels)
return text_size.x + parent->FromDIP(10);
}
std::vector<std::string> get_shaper_type_values()
{
if (auto* preset_bundle = wxGetApp().preset_bundle) {
auto printer_config = &preset_bundle->printers.get_edited_preset().config;
if (auto* gcode_flavor_option = printer_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")) {
switch (gcode_flavor_option->value) {
case GCodeFlavor::gcfKlipper:
return {"Default", "ZV", "MZV", "ZVD", "EI", "2HUMP_EI", "3HUMP_EI"};
case GCodeFlavor::gcfRepRapFirmware:
return {"Default", "MZV", "ZVD", "ZVDD", "ZVDDD", "EI2", "EI3", "DAA"};
case GCodeFlavor::gcfMarlinFirmware:
return {"ZV"};
default:
break;
}
}
}
return {"Default"};
}
std::vector<wxString> make_shaper_type_labels()
{
auto values = get_shaper_type_values();
if (values.empty())
values.emplace_back("");
std::vector<wxString> labels;
labels.reserve(values.size());
for (const auto& label : values)
labels.emplace_back(wxString::FromUTF8(label.c_str()));
return labels;
}
}
PA_Calibration_Dlg::PA_Calibration_Dlg(wxWindow* parent, wxWindowID id, Plater* plater)
@@ -763,6 +798,12 @@ Input_Shaping_Freq_Test_Dlg::Input_Shaping_Freq_Test_Dlg(wxWindow* parent, wxWin
SetForegroundColour(wxColour("#363636"));
SetFont(Label::Body_14);
const auto* preset_bundle = wxGetApp().preset_bundle;
const auto* gcode_flavor_option = (preset_bundle != nullptr)
? preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")
: nullptr;
const bool reprap_firmware = gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfRepRapFirmware;
wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL);
SetSizer(v_sizer);
@@ -774,8 +815,41 @@ Input_Shaping_Freq_Test_Dlg::Input_Shaping_Freq_Test_Dlg(wxWindow* parent, wxWin
model_box->Add(m_rbModel, 0, wxALL | wxEXPAND, FromDIP(4));
v_sizer->Add(model_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
// Input shaper type selection
auto labeled_box_type = new LabeledStaticBox(this, _L("Input shaper type"));
auto type_box = new wxStaticBoxSizer(labeled_box_type, wxVERTICAL);
auto type_labels = make_shaper_type_labels();
m_rbType = new RadioGroup(this, type_labels, wxVERTICAL, 3);
type_box->Add(m_rbType, 0, wxALL | wxEXPAND, FromDIP(4));
m_rbType->SetSelection(0);
// Determine firmware-specific note
wxString firmware_note = "Please ensure the selected type is compatible with your firmware version.";
if (gcode_flavor_option) {
switch (gcode_flavor_option->value) {
case GCodeFlavor::gcfMarlinFirmware:
case GCodeFlavor::gcfMarlinLegacy:
firmware_note = "Marlin version => 2.1.2\nFixed-Time motion not yet implemented.";
break;
case GCodeFlavor::gcfKlipper:
firmware_note = "Klipper version => 0.9.0";
break;
case GCodeFlavor::gcfRepRapFirmware:
firmware_note = "RepRap firmware version => 3.4.0\nCheck your firmware documentation for supported shaper types.";
break;
default:
break;
}
}
auto type_note = new wxStaticText(this, wxID_ANY, firmware_note, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
type_note->SetForegroundColour(wxColour(128, 128, 128));
type_box->Add(type_note, 0, wxALL, FromDIP(5));
v_sizer->Add(type_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
// Settings
wxString x_axis_str = "X " + _L("Start / End") + ": ";
wxString x_axis_str = reprap_firmware ? _L("Frequency (Start / End): ") : "X " + _L("Start / End") + ": ";
wxString y_axis_str = "Y " + _L("Start / End") + ": ";
int text_max = GetTextMax(this, std::vector<wxString>{x_axis_str, y_axis_str});
@@ -807,12 +881,24 @@ Input_Shaping_Freq_Test_Dlg::Input_Shaping_Freq_Test_Dlg(wxWindow* parent, wxWin
m_tiFreqStartY->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
m_tiFreqEndY = new TextInput(this, std::to_string(110), "Hz", "", wxDefaultPosition, ti_size);
m_tiFreqEndY->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
y_freq_sizer->Add(start_y_text , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2));
y_freq_sizer->Add(m_tiFreqStartY, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2));
y_freq_sizer->Add(m_tiFreqEndY , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2));
settings_sizer->Add(y_freq_sizer, 0, wxLEFT, FromDIP(3));
if (reprap_firmware) {
m_tiFreqStartY->GetTextCtrl()->SetValue(m_tiFreqStartX->GetTextCtrl()->GetValue());
m_tiFreqEndY->GetTextCtrl()->SetValue(m_tiFreqEndX->GetTextCtrl()->GetValue());
start_y_text->Hide();
m_tiFreqStartY->Hide();
m_tiFreqEndY->Hide();
settings_sizer->Hide(y_freq_sizer);
start_x_text->SetLabel(_L("Frequency (Start / End): "));
m_tiFreqStartX->GetTextCtrl()->SetToolTip(_L("RepRap firmware uses the same frequency range for both axes."));
m_tiFreqEndX->GetTextCtrl()->SetToolTip(_L("RepRap firmware uses the same frequency range for both axes."));
}
// Damping Factor
wxString damping_factor_str = _L("Damp: ");
auto damping_factor_sizer = new wxBoxSizer(wxHORIZONTAL);
@@ -826,8 +912,7 @@ Input_Shaping_Freq_Test_Dlg::Input_Shaping_Freq_Test_Dlg(wxWindow* parent, wxWin
settings_sizer->AddSpacer(FromDIP(5));
// Add a note explaining that 0 means use default value
auto note_text = new wxStaticText(this, wxID_ANY, _L("Recommended: Set Damp to 0.\nThis will use the printer's default or the last saved value."), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
auto note_text = new wxStaticText(this, wxID_ANY, _L("Recommended: Set Damp to 0.\nThis will use the printer's default or saved value."), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
note_text->SetForegroundColour(wxColour(128, 128, 128));
settings_sizer->Add(note_text, 0, wxALL, FromDIP(5));
@@ -855,15 +940,29 @@ void Input_Shaping_Freq_Test_Dlg::on_start(wxCommandEvent& event) {
bool read_double = false;
read_double = m_tiFreqStartX->GetTextCtrl()->GetValue().ToDouble(&m_params.freqStartX);
read_double = read_double && m_tiFreqEndX->GetTextCtrl()->GetValue().ToDouble(&m_params.freqEndX);
read_double = read_double && m_tiFreqStartY->GetTextCtrl()->GetValue().ToDouble(&m_params.freqStartY);
read_double = read_double && m_tiFreqEndY->GetTextCtrl()->GetValue().ToDouble(&m_params.freqEndY);
const auto* preset_bundle = wxGetApp().preset_bundle;
const auto* gcode_flavor_option = (preset_bundle != nullptr)
? preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")
: nullptr;
const bool reprap_firmware = gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfRepRapFirmware;
if (!reprap_firmware) {
read_double = read_double && m_tiFreqStartY->GetTextCtrl()->GetValue().ToDouble(&m_params.freqStartY);
read_double = read_double && m_tiFreqEndY->GetTextCtrl()->GetValue().ToDouble(&m_params.freqEndY);
} else {
m_params.freqStartY = m_params.freqStartX;
m_params.freqEndY = m_params.freqEndX;
m_tiFreqStartY->GetTextCtrl()->SetValue(m_tiFreqStartX->GetTextCtrl()->GetValue());
m_tiFreqEndY->GetTextCtrl()->SetValue(m_tiFreqEndX->GetTextCtrl()->GetValue());
}
read_double = read_double && m_tiDampingFactor->GetTextCtrl()->GetValue().ToDouble(&m_params.start);
if (!read_double ||
m_params.freqStartX < 0 || m_params.freqEndX > 500 ||
m_params.freqStartY < 0 || m_params.freqEndX > 500 ||
(!reprap_firmware && (m_params.freqStartY < 0 || m_params.freqEndY > 500)) ||
m_params.freqStartX >= m_params.freqEndX ||
m_params.freqStartY >= m_params.freqEndY) {
(!reprap_firmware && m_params.freqStartY >= m_params.freqEndY)) {
MessageDialog msg_dlg(nullptr, _L("Please input valid values:\n(0 < FreqStart < FreqEnd < 500)"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
@@ -875,6 +974,16 @@ void Input_Shaping_Freq_Test_Dlg::on_start(wxCommandEvent& event) {
return;
}
auto shaper_values = get_shaper_type_values();
int type_selection = m_rbType->GetSelection();
if (shaper_values.empty()) {
m_params.shaper_type.clear();
} else {
if (type_selection < 0 || type_selection >= static_cast<int>(shaper_values.size()))
type_selection = 0;
m_params.shaper_type = shaper_values[static_cast<size_t>(type_selection)];
}
m_params.mode = CalibMode::Calib_Input_shaping_freq;
// Set model type based on selection
@@ -899,6 +1008,12 @@ Input_Shaping_Damp_Test_Dlg::Input_Shaping_Damp_Test_Dlg(wxWindow* parent, wxWin
SetForegroundColour(wxColour("#363636"));
SetFont(Label::Body_14);
const auto* preset_bundle = wxGetApp().preset_bundle;
const auto* gcode_flavor_option = (preset_bundle != nullptr)
? preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")
: nullptr;
const bool reprap_firmware = gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfRepRapFirmware;
wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL);
SetSizer(v_sizer);
@@ -910,8 +1025,41 @@ Input_Shaping_Damp_Test_Dlg::Input_Shaping_Damp_Test_Dlg(wxWindow* parent, wxWin
model_box->Add(m_rbModel, 0, wxALL | wxEXPAND, FromDIP(4));
v_sizer->Add(model_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
// Input shaper type selection
auto labeled_box_type = new LabeledStaticBox(this, _L("Input shaper type"));
auto type_box = new wxStaticBoxSizer(labeled_box_type, wxVERTICAL);
auto type_labels = make_shaper_type_labels();
m_rbType = new RadioGroup(this, type_labels, wxVERTICAL, 3);
type_box->Add(m_rbType, 0, wxALL | wxEXPAND, FromDIP(4));
m_rbType->SetSelection(0);
// Determine firmware-specific note
wxString firmware_note = "Check firmware compatibility.";
if (gcode_flavor_option) {
switch (gcode_flavor_option->value) {
case GCodeFlavor::gcfMarlinFirmware:
case GCodeFlavor::gcfMarlinLegacy:
firmware_note = "Marlin version => 2.1.2\nFixed-Time motion not yet implemented.";
break;
case GCodeFlavor::gcfKlipper:
firmware_note = "Klipper version => 0.9.0";
break;
case GCodeFlavor::gcfRepRapFirmware:
firmware_note = "RepRap firmware version => 3.4.0\nCheck your firmware documentation for supported shaper types.";
break;
default:
break;
}
}
auto type_note = new wxStaticText(this, wxID_ANY, firmware_note, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
type_note->SetForegroundColour(wxColour(128, 128, 128));
type_box->Add(type_note, 0, wxALL, FromDIP(5));
v_sizer->Add(type_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
// Settings
wxString freq_str = _L("Frequency") + " X / Y: ";
wxString freq_str = reprap_firmware ? _L("Frequency: ") : _L("Frequency") + " X / Y: ";
wxString damp_str = _L("Damp") + " " + _L("Start / End") + ": ";
int text_max = GetTextMax(this, std::vector<wxString>{freq_str, damp_str});
@@ -933,7 +1081,14 @@ Input_Shaping_Damp_Test_Dlg::Input_Shaping_Damp_Test_Dlg(wxWindow* parent, wxWin
freq_sizer->Add(m_tiFreqX, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2));
freq_sizer->Add(m_tiFreqY, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2));
settings_sizer->Add(freq_sizer, 0, wxLEFT, FromDIP(3));
if (reprap_firmware) {
m_tiFreqY->GetTextCtrl()->SetValue(m_tiFreqX->GetTextCtrl()->GetValue());
m_tiFreqY->Hide();
freq_text->SetLabel(freq_str);
m_tiFreqX->GetTextCtrl()->SetToolTip(_L("RepRap firmware uses the same frequency for both axes."));
}
// Damping Factor Start and End
auto damp_sizer = new wxBoxSizer(wxHORIZONTAL);
auto damp_text = new wxStaticText(this, wxID_ANY, damp_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
@@ -976,13 +1131,24 @@ Input_Shaping_Damp_Test_Dlg::~Input_Shaping_Damp_Test_Dlg() {
void Input_Shaping_Damp_Test_Dlg::on_start(wxCommandEvent& event) {
bool read_double = false;
read_double = m_tiFreqX->GetTextCtrl()->GetValue().ToDouble(&m_params.freqStartX);
read_double = read_double && m_tiFreqY->GetTextCtrl()->GetValue().ToDouble(&m_params.freqStartY);
const auto* preset_bundle = wxGetApp().preset_bundle;
const auto* gcode_flavor_option = (preset_bundle != nullptr)
? preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")
: nullptr;
const bool reprap_firmware = gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfRepRapFirmware;
if (!reprap_firmware) {
read_double = read_double && m_tiFreqY->GetTextCtrl()->GetValue().ToDouble(&m_params.freqStartY);
} else {
m_params.freqStartY = m_params.freqStartX;
m_tiFreqY->GetTextCtrl()->SetValue(m_tiFreqX->GetTextCtrl()->GetValue());
}
read_double = read_double && m_tiDampingFactorStart->GetTextCtrl()->GetValue().ToDouble(&m_params.start);
read_double = read_double && m_tiDampingFactorEnd->GetTextCtrl()->GetValue().ToDouble(&m_params.end);
if (!read_double ||
m_params.freqStartX < 0 || m_params.freqStartX > 500 ||
m_params.freqStartY < 0 || m_params.freqStartY > 500 ) {
(!reprap_firmware && (m_params.freqStartY < 0 || m_params.freqStartY > 500))) {
MessageDialog msg_dlg(nullptr, _L("Please input valid values:\n(0 < Freq < 500)"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
@@ -995,6 +1161,16 @@ void Input_Shaping_Damp_Test_Dlg::on_start(wxCommandEvent& event) {
return;
}
auto shaper_values = get_shaper_type_values();
int type_selection = m_rbType->GetSelection();
if (shaper_values.empty()) {
m_params.shaper_type.clear();
} else {
if (type_selection < 0 || type_selection >= static_cast<int>(shaper_values.size()))
type_selection = 0;
m_params.shaper_type = shaper_values[static_cast<size_t>(type_selection)];
}
m_params.mode = CalibMode::Calib_Input_shaping_damp;
// Set model type based on selection

View File

@@ -134,6 +134,7 @@ protected:
Calib_Params m_params;
RadioGroup* m_rbModel;
RadioGroup* m_rbType;
TextInput* m_tiFreqStartX;
TextInput* m_tiFreqEndX;
TextInput* m_tiFreqStartY;
@@ -155,6 +156,7 @@ protected:
Calib_Params m_params;
RadioGroup* m_rbModel;
RadioGroup* m_rbType;
TextInput* m_tiFreqX;
TextInput* m_tiFreqY;
TextInput* m_tiDampingFactorStart;