Vfa calibs - Input Shaping & Junction Deviation (#9160)
@RF47 and I have been working on a **two-step input shaping calibration** to help fine-tune print quality and Junction Deviation Test for Marlin2 printers. This is based on [Klipper's Resonance Compensation](https://www.klipper3d.org/Resonance_Compensation.html#resonance-compensation), [Marlin’s M593 G-code](https://marlinfw.org/docs/gcode/M593.html), discussions from [SoftFever/OrcaSlicer#1820](https://github.com/SoftFever/OrcaSlicer/issues/1820), some elements from the [input_shaping branch](https://github.com/SoftFever/OrcaSlicer/tree/feature/input_shaping) and Junction Deviation [Marlin Documentation](https://marlinfw.org/docs/configuration/configuration.html#junction-deviation-) This is for Marlin only, but I'm working on a future Klipper-compatible version here: [VFA-Calibs+Klipper](https://github.com/ianalexis/OrcaSlicer/tree/VFA-Calibs%2BKlipper). However, we don't own a Klipper machine, so we're unsure how to improve it or verify if it works correctly. ### Calibration Steps 1. **Frequency Test** – Helps identify the optimal input shaping frequency. 2. **Damping Test** – Fine-tunes the damping ratio for smoother prints. ### Screenshots         ## Tests - Marlin tested on **Ender 3-class printers** (@RF47 and @ianalexis) - Klipper tested in Voron 2.4 and an FLSun T1 Pro @ShaneDelmore - Tested in Windows and MacOs.
This commit is contained in:
@@ -3749,25 +3749,68 @@ LayerResult GCode::process_layer(
|
||||
//BBS: set layer time fan speed after layer change gcode
|
||||
gcode += ";_SET_FAN_SPEED_CHANGING_LAYER\n";
|
||||
|
||||
if (print.calib_mode() == CalibMode::Calib_PA_Tower) {
|
||||
gcode += writer().set_pressure_advance(print.calib_params().start + static_cast<int>(print_z) * print.calib_params().step);
|
||||
} else if (print.calib_mode() == CalibMode::Calib_Temp_Tower) {
|
||||
auto offset = static_cast<unsigned int>(print_z / 10.001) * 5;
|
||||
gcode += writer().set_temperature(print.calib_params().start - offset);
|
||||
} else if (print.calib_mode() == CalibMode::Calib_VFA_Tower) {
|
||||
auto _speed = print.calib_params().start + std::floor(print_z / 5.0) * print.calib_params().step;
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
|
||||
} else if (print.calib_mode() == CalibMode::Calib_Vol_speed_Tower) {
|
||||
auto _speed = print.calib_params().start + print_z * print.calib_params().step;
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
|
||||
}
|
||||
else if (print.calib_mode() == CalibMode::Calib_Retraction_tower) {
|
||||
auto _length = print.calib_params().start + std::floor(std::max(0.0,print_z-0.4)) * print.calib_params().step;
|
||||
DynamicConfig _cfg;
|
||||
_cfg.set_key_value("retraction_length", new ConfigOptionFloats{_length});
|
||||
writer().config.apply(_cfg);
|
||||
sprintf(buf, "; Calib_Retraction_tower: Z_HEIGHT: %g, length:%g\n", print_z, _length);
|
||||
gcode += buf;
|
||||
//Calibration Layer-specific GCode
|
||||
switch (print.calib_mode()) {
|
||||
case CalibMode::Calib_PA_Tower: {
|
||||
gcode += writer().set_pressure_advance(print.calib_params().start + static_cast<int>(print_z) * print.calib_params().step);
|
||||
break;
|
||||
}
|
||||
case CalibMode::Calib_Temp_Tower: {
|
||||
auto offset = static_cast<unsigned int>(print_z / 10.001) * 5;
|
||||
gcode += writer().set_temperature(print.calib_params().start - offset);
|
||||
break;
|
||||
}
|
||||
case CalibMode::Calib_VFA_Tower: {
|
||||
auto _speed = print.calib_params().start + std::floor(print_z / 5.0) * print.calib_params().step;
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
|
||||
break;
|
||||
}
|
||||
case CalibMode::Calib_Vol_speed_Tower: {
|
||||
auto _speed = print.calib_params().start + print_z * print.calib_params().step;
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
|
||||
break;
|
||||
}
|
||||
case CalibMode::Calib_Retraction_tower: {
|
||||
auto _length = print.calib_params().start + std::floor(std::max(0.0,print_z-0.4)) * print.calib_params().step;
|
||||
DynamicConfig _cfg;
|
||||
_cfg.set_key_value("retraction_length", new ConfigOptionFloats{_length});
|
||||
writer().config.apply(_cfg);
|
||||
sprintf(buf, "; Calib_Retraction_tower: Z_HEIGHT: %g, length:%g\n", print_z, _length);
|
||||
gcode += buf;
|
||||
break;
|
||||
}
|
||||
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) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
case CalibMode::Calib_Junction_Deviation: {
|
||||
gcode += writer().set_junction_deviation(print.calib_params().start + ((print.calib_params().end)-(print.calib_params().start)) * (m_layer_index) / (m_layer_count));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//BBS
|
||||
|
||||
@@ -313,6 +313,16 @@ 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");
|
||||
}
|
||||
gcode << "M205 J" << junction_deviation << " ; Junction Deviation\n";
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
|
||||
std::string GCodeWriter::set_pressure_advance(double pa) const
|
||||
{
|
||||
std::ostringstream gcode;
|
||||
@@ -333,6 +343,49 @@ 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
|
||||
{
|
||||
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));
|
||||
}
|
||||
std::ostringstream gcode;
|
||||
if (FLAVOR_IS(gcfKlipper)) {
|
||||
gcode << "SET_INPUT_SHAPER";
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
if (freq > 0.0f) {
|
||||
gcode << " SHAPER_FREQ_X=" << std::fixed << std::setprecision(2) << freq << " SHAPER_FREQ_Y=" << std::fixed << std::setprecision(2) << freq;
|
||||
}
|
||||
if (damp > 0.0f) {
|
||||
gcode << " DAMPING_RATIO_X=" << damp << " DAMPING_RATIO_Y=" << damp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gcode << "M593";
|
||||
if (axis != 'A')
|
||||
{
|
||||
gcode << " " << axis;
|
||||
}
|
||||
if (freq > 0.0f)
|
||||
{
|
||||
gcode << " F" << std::fixed << std::setprecision(2) << freq;
|
||||
}
|
||||
if (damp > 0.0f)
|
||||
{
|
||||
gcode << " D" << std::fixed << std::setprecision(2) << damp;
|
||||
}
|
||||
}
|
||||
gcode << "; Override input shaping value\n";
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
|
||||
std::string GCodeWriter::reset_e(bool force)
|
||||
|
||||
@@ -53,7 +53,9 @@ public:
|
||||
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_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 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
|
||||
|
||||
@@ -879,4 +879,6 @@ double CalibPressureAdvancePattern::pattern_shift() const
|
||||
{
|
||||
return (wall_count() - 1) * line_spacing_first_layer() + line_width_first_layer() + m_glyph_padding_horizontal;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
@@ -21,7 +21,10 @@ enum class CalibMode : int {
|
||||
Calib_Temp_Tower,
|
||||
Calib_Vol_speed_Tower,
|
||||
Calib_VFA_Tower,
|
||||
Calib_Retraction_tower
|
||||
Calib_Retraction_tower,
|
||||
Calib_Input_shaping_freq,
|
||||
Calib_Input_shaping_damp,
|
||||
Calib_Junction_Deviation
|
||||
};
|
||||
|
||||
enum class CalibState { Start = 0, Preset, Calibration, CoarseSave, FineCalibration, Save, Finish };
|
||||
@@ -31,7 +34,8 @@ struct Calib_Params
|
||||
Calib_Params() : mode(CalibMode::Calib_None){};
|
||||
double start, end, step;
|
||||
bool print_numbers;
|
||||
|
||||
double freqStartX, freqEndX, freqStartY, freqEndY;
|
||||
int test_model;
|
||||
std::vector<double> accelerations;
|
||||
std::vector<double> speeds;
|
||||
|
||||
@@ -335,4 +339,5 @@ private:
|
||||
const double m_glyph_padding_horizontal{1};
|
||||
const double m_glyph_padding_vertical{1};
|
||||
};
|
||||
} // namespace Slic3r
|
||||
|
||||
} // namespace Slic3r
|
||||
@@ -44,6 +44,12 @@ static wxString get_default_name(wxString filament_name, CalibMode mode){
|
||||
break;
|
||||
case Slic3r::CalibMode::Calib_Retraction_tower:
|
||||
break;
|
||||
case Slic3r::CalibMode::Calib_Input_shaping_freq:
|
||||
break;
|
||||
case Slic3r::CalibMode::Calib_Input_shaping_damp:
|
||||
break;
|
||||
case Slic3r::CalibMode::Calib_Junction_Deviation:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2975,6 +2975,43 @@ void MainFrame::init_menubar_as_editor()
|
||||
},
|
||||
"", nullptr,
|
||||
[this]() {return m_plater->is_view3D_shown();; }, this);
|
||||
|
||||
// Input Shaping calibrations
|
||||
auto input_shaping_menu = new wxMenu();
|
||||
|
||||
append_menu_item(
|
||||
input_shaping_menu, wxID_ANY, _L("Input Shaping Frequency"), _L("Input Shaping Frequency"),
|
||||
[this](wxCommandEvent&) {
|
||||
if (!m_IS_freq_calib_dlg)
|
||||
m_IS_freq_calib_dlg = new Input_Shaping_Freq_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater);
|
||||
m_IS_freq_calib_dlg->ShowModal();
|
||||
},
|
||||
"", nullptr,
|
||||
[this]() {return m_plater->is_view3D_shown();; }, this);
|
||||
|
||||
append_menu_item(
|
||||
input_shaping_menu, wxID_ANY, _L("Input Shaping Damping/zeta factor"), _L("Input Shaping Damping/zeta factor"),
|
||||
[this](wxCommandEvent&) {
|
||||
if (!m_IS_damp_calib_dlg)
|
||||
m_IS_damp_calib_dlg = new Input_Shaping_Damp_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater);
|
||||
m_IS_damp_calib_dlg->ShowModal();
|
||||
},
|
||||
"", nullptr,
|
||||
[this]() {return m_plater->is_view3D_shown();; }, this);
|
||||
|
||||
m_topbar->GetCalibMenu()->AppendSubMenu(input_shaping_menu, _L("Input Shaping"));
|
||||
|
||||
// Add Junction Deviation option to More menu
|
||||
append_menu_item(
|
||||
advance_menu, wxID_ANY, _L("Junction Deviation"), _L("Junction Deviation calibration"),
|
||||
[this](wxCommandEvent&) {
|
||||
if (!m_junction_deviation_calib_dlg)
|
||||
m_junction_deviation_calib_dlg = new Junction_Deviation_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater);
|
||||
m_junction_deviation_calib_dlg->ShowModal();
|
||||
},
|
||||
"", nullptr,
|
||||
[this]() {return m_plater->is_view3D_shown();; }, this);
|
||||
|
||||
m_topbar->GetCalibMenu()->AppendSubMenu(advance_menu, _L("More..."));
|
||||
|
||||
// help
|
||||
@@ -3073,6 +3110,41 @@ void MainFrame::init_menubar_as_editor()
|
||||
}, "", nullptr,
|
||||
[this]() {return m_plater->is_view3D_shown();; }, this);
|
||||
|
||||
// Add Junction Deviation option to More menu
|
||||
append_menu_item(
|
||||
advance_menu, wxID_ANY, _L("Junction Deviation"), _L("Junction Deviation calibration"),
|
||||
[this](wxCommandEvent&) {
|
||||
if (!m_junction_deviation_calib_dlg)
|
||||
m_junction_deviation_calib_dlg = new Junction_Deviation_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater);
|
||||
m_junction_deviation_calib_dlg->ShowModal();
|
||||
}, "", nullptr,
|
||||
[this]() {return m_plater->is_view3D_shown();; }, this);
|
||||
|
||||
// Input Shaping calibrations
|
||||
auto input_shaping_menu = new wxMenu();
|
||||
|
||||
append_menu_item(
|
||||
input_shaping_menu, wxID_ANY, _L("Input Shaping Frequency"), _L("Input Shaping Frequency"),
|
||||
[this](wxCommandEvent&) {
|
||||
if (!m_IS_freq_calib_dlg)
|
||||
m_IS_freq_calib_dlg = new Input_Shaping_Freq_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater);
|
||||
m_IS_freq_calib_dlg->ShowModal();
|
||||
},
|
||||
"", nullptr,
|
||||
[this]() {return m_plater->is_view3D_shown();; }, this);
|
||||
|
||||
append_menu_item(
|
||||
input_shaping_menu, wxID_ANY, _L("Input Shaping Damping/zeta factor"), _L("Input Shaping Damping/zeta factor"),
|
||||
[this](wxCommandEvent&) {
|
||||
if (!m_IS_damp_calib_dlg)
|
||||
m_IS_damp_calib_dlg = new Input_Shaping_Damp_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater);
|
||||
m_IS_damp_calib_dlg->ShowModal();
|
||||
},
|
||||
"", nullptr,
|
||||
[this]() {return m_plater->is_view3D_shown();; }, this);
|
||||
|
||||
calib_menu->AppendSubMenu(input_shaping_menu, _L("Input Shaping"));
|
||||
|
||||
append_submenu(calib_menu, advance_menu, wxID_ANY, _L("More..."), _L("More calibrations"), "",
|
||||
[this]() {return m_plater->is_view3D_shown();; });
|
||||
// help
|
||||
|
||||
@@ -354,6 +354,9 @@ public:
|
||||
MaxVolumetricSpeed_Test_Dlg* m_vol_test_dlg { nullptr };
|
||||
VFA_Test_Dlg* m_vfa_test_dlg { nullptr };
|
||||
Retraction_Test_Dlg* m_retraction_calib_dlg{ nullptr };
|
||||
Input_Shaping_Freq_Test_Dlg* m_IS_freq_calib_dlg{ nullptr };
|
||||
Input_Shaping_Damp_Test_Dlg* m_IS_damp_calib_dlg{ nullptr };
|
||||
Junction_Deviation_Test_Dlg* m_junction_deviation_calib_dlg{ nullptr };
|
||||
|
||||
// BBS. Replace title bar and menu bar with top bar.
|
||||
BBLTopbar* m_topbar{ nullptr };
|
||||
|
||||
@@ -10192,6 +10192,124 @@ void Plater::calib_VFA(const Calib_Params& params)
|
||||
|
||||
p->background_process.fff_print()->set_calib_params(params);
|
||||
}
|
||||
|
||||
void Plater::calib_input_shaping_freq(const Calib_Params& params)
|
||||
{
|
||||
const auto calib_input_shaping_name = wxString::Format(L"Input shaping Frequency test");
|
||||
new_project(false, false, calib_input_shaping_name);
|
||||
wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor));
|
||||
if (params.mode != CalibMode::Calib_Input_shaping_freq)
|
||||
return;
|
||||
|
||||
add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.stl" : "/calib/input_shaping/fast_input_shaping_test.stl"));
|
||||
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
|
||||
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});
|
||||
filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats { 200 });
|
||||
filament_config->set_key_value("enable_pressure_advance", new ConfigOptionBools {false });
|
||||
filament_config->set_key_value("pressure_advance", new ConfigOptionFloats { 0.0 });
|
||||
print_config->set_key_value("enable_overhang_speed", new ConfigOptionBool { false });
|
||||
print_config->set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
|
||||
print_config->set_key_value("wall_loops", new ConfigOptionInt(1));
|
||||
print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0));
|
||||
print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
|
||||
print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
|
||||
print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false));
|
||||
print_config->set_key_value("spiral_mode", new ConfigOptionBool(true));
|
||||
print_config->set_key_value("spiral_mode_smooth", new ConfigOptionBool(true));
|
||||
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));
|
||||
|
||||
changed_objects({ 0 });
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
|
||||
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings();
|
||||
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_ui_from_settings();
|
||||
|
||||
p->background_process.fff_print()->set_calib_params(params);
|
||||
}
|
||||
|
||||
void Plater::calib_input_shaping_damp(const Calib_Params& params)
|
||||
{
|
||||
const auto calib_input_shaping_name = wxString::Format(L"Input shaping Damping test");
|
||||
new_project(false, false, calib_input_shaping_name);
|
||||
wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor));
|
||||
if (params.mode != CalibMode::Calib_Input_shaping_damp)
|
||||
return;
|
||||
|
||||
add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.stl" : "/calib/input_shaping/fast_input_shaping_test.stl"));
|
||||
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
|
||||
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});
|
||||
filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats { 200 });
|
||||
filament_config->set_key_value("enable_pressure_advance", new ConfigOptionBools{false});
|
||||
filament_config->set_key_value("pressure_advance", new ConfigOptionFloats{0.0});
|
||||
print_config->set_key_value("enable_overhang_speed", new ConfigOptionBool{false});
|
||||
print_config->set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
|
||||
print_config->set_key_value("wall_loops", new ConfigOptionInt(1));
|
||||
print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0));
|
||||
print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
|
||||
print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
|
||||
print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false));
|
||||
print_config->set_key_value("spiral_mode", new ConfigOptionBool(true));
|
||||
print_config->set_key_value("spiral_mode_smooth", new ConfigOptionBool(true));
|
||||
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));
|
||||
|
||||
changed_objects({ 0 });
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
|
||||
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings();
|
||||
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_ui_from_settings();
|
||||
|
||||
p->background_process.fff_print()->set_calib_params(params);
|
||||
}
|
||||
|
||||
void Plater::calib_junction_deviation(const Calib_Params& params)
|
||||
{
|
||||
const auto calib_junction_deviation = wxString::Format(L"Input shaping Damping test");
|
||||
new_project(false, false, calib_junction_deviation);
|
||||
wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor));
|
||||
if (params.mode != CalibMode::Calib_Junction_Deviation)
|
||||
return;
|
||||
|
||||
add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.stl" : "/calib/input_shaping/fast_input_shaping_test.stl"));
|
||||
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
|
||||
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});
|
||||
filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{200});
|
||||
filament_config->set_key_value("enable_pressure_advance", new ConfigOptionBools{false});
|
||||
filament_config->set_key_value("pressure_advance", new ConfigOptionFloats{0.0});
|
||||
print_config->set_key_value("enable_overhang_speed", new ConfigOptionBool{false});
|
||||
print_config->set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
|
||||
print_config->set_key_value("wall_loops", new ConfigOptionInt(1));
|
||||
print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0));
|
||||
print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
|
||||
print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
|
||||
print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false));
|
||||
print_config->set_key_value("spiral_mode", new ConfigOptionBool(true));
|
||||
print_config->set_key_value("spiral_mode_smooth", new ConfigOptionBool(true));
|
||||
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));
|
||||
|
||||
changed_objects({ 0 });
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
|
||||
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings();
|
||||
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_ui_from_settings();
|
||||
|
||||
p->background_process.fff_print()->set_calib_params(params);
|
||||
}
|
||||
|
||||
BuildVolume_Type Plater::get_build_volume_type() const { return p->bed.get_build_volume_type(); }
|
||||
|
||||
void Plater::import_zip_archive()
|
||||
|
||||
@@ -273,6 +273,9 @@ public:
|
||||
void calib_max_vol_speed(const Calib_Params& params);
|
||||
void calib_retraction(const Calib_Params& params);
|
||||
void calib_VFA(const Calib_Params& params);
|
||||
void calib_input_shaping_freq(const Calib_Params& params);
|
||||
void calib_input_shaping_damp(const Calib_Params& params);
|
||||
void calib_junction_deviation(const Calib_Params& params);
|
||||
|
||||
BuildVolume_Type get_build_volume_type() const;
|
||||
|
||||
|
||||
@@ -789,5 +789,391 @@ void Retraction_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) {
|
||||
|
||||
}
|
||||
|
||||
// Input_Shaping_Freq_Test_Dlg
|
||||
//
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
Input_Shaping_Freq_Test_Dlg::Input_Shaping_Freq_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater)
|
||||
: DPIDialog(parent, id, _L("Input shaping Frequency test"), wxDefaultPosition, parent->FromDIP(wxSize(-1, 280)), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), m_plater(plater)
|
||||
{
|
||||
wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
SetSizer(v_sizer);
|
||||
|
||||
// Model selection
|
||||
wxString m_rbModelChoices[] = { _L("Ringing Tower"), _L("Fast Tower") };
|
||||
int m_rbModelNChoices = sizeof(m_rbModelChoices) / sizeof(wxString);
|
||||
m_rbModel = new wxRadioBox(this, wxID_ANY, _L("Test model"), wxDefaultPosition, wxDefaultSize, m_rbModelNChoices, m_rbModelChoices, 1, wxRA_SPECIFY_ROWS);
|
||||
m_rbModel->SetSelection(0);
|
||||
v_sizer->Add(m_rbModel, 0, wxALL | wxEXPAND, 5);
|
||||
|
||||
// Settings
|
||||
//
|
||||
wxString start_x_str = _L("Start X: ");
|
||||
wxString end_x_str = _L("End X: ");
|
||||
wxString start_y_str = _L("Start Y: ");
|
||||
wxString end_y_str = _L("End Y: ");
|
||||
auto text_size = wxWindow::GetTextExtent(start_x_str);
|
||||
text_size.IncTo(wxWindow::GetTextExtent(end_x_str));
|
||||
text_size.IncTo(wxWindow::GetTextExtent(start_y_str));
|
||||
text_size.IncTo(wxWindow::GetTextExtent(end_y_str));
|
||||
text_size.x = text_size.x * 1.5;
|
||||
wxStaticBoxSizer* settings_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _L("Frequency settings"));
|
||||
|
||||
auto st_size = FromDIP(wxSize(text_size.x, -1));
|
||||
auto ti_size = FromDIP(wxSize(90, -1));
|
||||
|
||||
// X axis frequencies
|
||||
auto x_freq_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto start_x_text = new wxStaticText(this, wxID_ANY, start_x_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiFreqStartX = new TextInput(this, std::to_string(15), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiFreqStartX->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
auto end_x_text = new wxStaticText(this, wxID_ANY, end_x_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiFreqEndX = new TextInput(this, std::to_string(60), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiFreqEndX->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
|
||||
x_freq_sizer->Add(start_x_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
x_freq_sizer->Add(m_tiFreqStartX, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
x_freq_sizer->Add(end_x_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
x_freq_sizer->Add(m_tiFreqEndX, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
settings_sizer->Add(x_freq_sizer);
|
||||
|
||||
// Y axis frequencies
|
||||
auto y_freq_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto start_y_text = new wxStaticText(this, wxID_ANY, start_y_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiFreqStartY = new TextInput(this, std::to_string(15), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiFreqStartY->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
auto end_y_text = new wxStaticText(this, wxID_ANY, end_y_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiFreqEndY = new TextInput(this, std::to_string(60), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiFreqEndY->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
|
||||
y_freq_sizer->Add(start_y_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
y_freq_sizer->Add(m_tiFreqStartY, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
y_freq_sizer->Add(end_y_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
y_freq_sizer->Add(m_tiFreqEndY, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
settings_sizer->Add(y_freq_sizer);
|
||||
|
||||
// Damping Factor
|
||||
wxString damping_factor_str = _L("Damp: ");
|
||||
auto damping_factor_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto damping_factor_text = new wxStaticText(this, wxID_ANY, damping_factor_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiDampingFactor = new TextInput(this, wxString::Format("%.2f", 0.35), "", "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiDampingFactor->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
|
||||
damping_factor_sizer->Add(damping_factor_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
damping_factor_sizer->Add(m_tiDampingFactor, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
settings_sizer->Add(damping_factor_sizer);
|
||||
|
||||
// Add a note explaining that 0 means use default value
|
||||
auto note_text = new wxStaticText(this, wxID_ANY, _L("Note: 0 Damp = Printer default."), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
note_text->SetForegroundColour(wxColour(128, 128, 128));
|
||||
settings_sizer->Add(note_text, 0, wxALL, 5);
|
||||
|
||||
v_sizer->Add(settings_sizer);
|
||||
v_sizer->Add(0, FromDIP(10), 0, wxEXPAND, 5);
|
||||
m_btnStart = new Button(this, _L("OK"));
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
|
||||
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
|
||||
|
||||
m_btnStart->SetBackgroundColor(btn_bg_green);
|
||||
m_btnStart->SetBorderColor(wxColour(0, 150, 136));
|
||||
m_btnStart->SetTextColor(wxColour("#FFFFFE"));
|
||||
m_btnStart->SetSize(wxSize(FromDIP(48), FromDIP(24)));
|
||||
m_btnStart->SetMinSize(wxSize(FromDIP(48), FromDIP(24)));
|
||||
m_btnStart->SetCornerRadius(FromDIP(3));
|
||||
m_btnStart->Bind(wxEVT_BUTTON, &Input_Shaping_Freq_Test_Dlg::on_start, this);
|
||||
v_sizer->Add(m_btnStart, 0, wxALL | wxALIGN_RIGHT, FromDIP(5));
|
||||
|
||||
m_btnStart->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Input_Shaping_Freq_Test_Dlg::on_start), NULL, this);
|
||||
|
||||
//wxGetApp().UpdateDlgDarkUI(this);//FIXME: dark mode background color
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
Input_Shaping_Freq_Test_Dlg::~Input_Shaping_Freq_Test_Dlg() {
|
||||
// Disconnect Events
|
||||
m_btnStart->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Input_Shaping_Freq_Test_Dlg::on_start), NULL, this);
|
||||
}
|
||||
|
||||
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);
|
||||
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 ||
|
||||
m_params.freqStartX >= m_params.freqEndX ||
|
||||
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;
|
||||
}
|
||||
|
||||
if (m_params.start < 0 || m_params.start >= 1) {
|
||||
MessageDialog msg_dlg(nullptr, _L("Please input a valid damping factor (0 < Damping/zeta factor <= 1)"), wxEmptyString, wxICON_WARNING | wxOK);
|
||||
msg_dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
|
||||
m_params.mode = CalibMode::Calib_Input_shaping_freq;
|
||||
|
||||
// Set model type based on selection
|
||||
m_params.test_model = m_rbModel->GetSelection() == 0 ? 0 : 1; // 0 = Ringing Tower, 1 = Fast Tower
|
||||
|
||||
m_plater->calib_input_shaping_freq(m_params);
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void Input_Shaping_Freq_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) {
|
||||
this->Refresh();
|
||||
Fit();
|
||||
}
|
||||
|
||||
// Input_Shaping_Damp_Test_Dlg
|
||||
//
|
||||
|
||||
Input_Shaping_Damp_Test_Dlg::Input_Shaping_Damp_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater)
|
||||
: DPIDialog(parent, id, _L("Input shaping Damp test"), wxDefaultPosition, parent->FromDIP(wxSize(-1, 280)), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), m_plater(plater)
|
||||
{
|
||||
wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
SetSizer(v_sizer);
|
||||
|
||||
// Model selection
|
||||
wxString m_rbModelChoices[] = { _L("Ringing Tower"), _L("Fast Tower") };
|
||||
int m_rbModelNChoices = sizeof(m_rbModelChoices) / sizeof(wxString);
|
||||
m_rbModel = new wxRadioBox(this, wxID_ANY, _L("Test model"), wxDefaultPosition, wxDefaultSize, m_rbModelNChoices, m_rbModelChoices, 1, wxRA_SPECIFY_ROWS);
|
||||
m_rbModel->SetSelection(0);
|
||||
v_sizer->Add(m_rbModel, 0, wxALL | wxEXPAND, 5);
|
||||
|
||||
// Settings
|
||||
//
|
||||
wxString freq_x_str = _L("Freq X: ");
|
||||
wxString freq_y_str = _L("Freq Y: ");
|
||||
wxString damp_start_str = _L("Start damp: ");
|
||||
wxString damp_end_str = _L("End damp: ");
|
||||
auto text_size = wxWindow::GetTextExtent(freq_x_str);
|
||||
text_size.IncTo(wxWindow::GetTextExtent(freq_y_str));
|
||||
text_size.IncTo(wxWindow::GetTextExtent(damp_start_str));
|
||||
text_size.IncTo(wxWindow::GetTextExtent(damp_end_str));
|
||||
text_size.x = text_size.x * 1.5;
|
||||
wxStaticBoxSizer* settings_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _L("Frequency settings"));
|
||||
|
||||
auto st_size = FromDIP(wxSize(text_size.x, -1));
|
||||
auto ti_size = FromDIP(wxSize(90, -1));
|
||||
|
||||
auto freq_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto freq_x_text = new wxStaticText(this, wxID_ANY, freq_x_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiFreqX = new TextInput(this, std::to_string(30), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiFreqX->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
auto freq_y_text = new wxStaticText(this, wxID_ANY, freq_y_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiFreqY = new TextInput(this, std::to_string(30), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiFreqY->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
|
||||
freq_sizer->Add(freq_x_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
freq_sizer->Add(m_tiFreqX, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
freq_sizer->Add(freq_y_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
freq_sizer->Add(m_tiFreqY, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
settings_sizer->Add(freq_sizer);
|
||||
|
||||
// Damping Factor Start and End
|
||||
auto damp_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto damp_start_text = new wxStaticText(this, wxID_ANY, damp_start_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiDampingFactorStart = new TextInput(this, wxString::Format("%.2f", 0.00), "", "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiDampingFactorStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
auto damp_end_text = new wxStaticText(this, wxID_ANY, damp_end_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiDampingFactorEnd = new TextInput(this, wxString::Format("%.2f", 0.40), "", "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiDampingFactorEnd->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
|
||||
damp_sizer->Add(damp_start_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
damp_sizer->Add(m_tiDampingFactorStart, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
damp_sizer->Add(damp_end_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
damp_sizer->Add(m_tiDampingFactorEnd, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
settings_sizer->Add(damp_sizer);
|
||||
|
||||
// Add a note to explain users to use their previously calculated frequency
|
||||
auto note_text = new wxStaticText(this, wxID_ANY, _L("Note: Use previously calculated frequencies."), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
note_text->SetForegroundColour(wxColour(128, 128, 128));
|
||||
settings_sizer->Add(note_text, 0, wxALL, 5);
|
||||
|
||||
note_text->SetForegroundColour(wxColour(128, 128, 128));
|
||||
settings_sizer->Add(note_text, 0, wxALL, 5);
|
||||
|
||||
v_sizer->Add(settings_sizer);
|
||||
v_sizer->Add(0, FromDIP(10), 0, wxEXPAND, 5);
|
||||
m_btnStart = new Button(this, _L("OK"));
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
|
||||
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
|
||||
|
||||
m_btnStart->SetBackgroundColor(btn_bg_green);
|
||||
m_btnStart->SetBorderColor(wxColour(0, 150, 136));
|
||||
m_btnStart->SetTextColor(wxColour("#FFFFFE"));
|
||||
m_btnStart->SetSize(wxSize(FromDIP(48), FromDIP(24)));
|
||||
m_btnStart->SetMinSize(wxSize(FromDIP(48), FromDIP(24)));
|
||||
m_btnStart->SetCornerRadius(FromDIP(3));
|
||||
m_btnStart->Bind(wxEVT_BUTTON, &Input_Shaping_Damp_Test_Dlg::on_start, this);
|
||||
v_sizer->Add(m_btnStart, 0, wxALL | wxALIGN_RIGHT, FromDIP(5));
|
||||
|
||||
m_btnStart->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Input_Shaping_Damp_Test_Dlg::on_start), NULL, this);
|
||||
|
||||
//wxGetApp().UpdateDlgDarkUI(this);//FIXME: dark mode background color
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
Input_Shaping_Damp_Test_Dlg::~Input_Shaping_Damp_Test_Dlg() {
|
||||
// Disconnect Events
|
||||
m_btnStart->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Input_Shaping_Damp_Test_Dlg::on_start), NULL, this);
|
||||
}
|
||||
|
||||
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);
|
||||
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 ) {
|
||||
MessageDialog msg_dlg(nullptr, _L("Please input valid values\n(0 < Freq < 500"), wxEmptyString, wxICON_WARNING | wxOK);
|
||||
msg_dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_params.start < 0 || m_params.end > 1
|
||||
|| m_params.start >= m_params.end) {
|
||||
MessageDialog msg_dlg(nullptr, _L("Please input a valid damping factor (0 <= DampingStart < DampingEnd <= 1)"), wxEmptyString, wxICON_WARNING | wxOK);
|
||||
msg_dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
|
||||
m_params.mode = CalibMode::Calib_Input_shaping_damp;
|
||||
|
||||
// Set model type based on selection
|
||||
m_params.test_model = m_rbModel->GetSelection() == 0 ? 0 : 1; // 0 = Ringing Tower, 1 = Fast Tower
|
||||
|
||||
m_plater->calib_input_shaping_damp(m_params);
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void Input_Shaping_Damp_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) {
|
||||
this->Refresh();
|
||||
Fit();
|
||||
}
|
||||
|
||||
// Junction_Deviation_Test_Dlg
|
||||
//
|
||||
|
||||
Junction_Deviation_Test_Dlg::Junction_Deviation_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater)
|
||||
: DPIDialog(parent, id, _L("Junction Deviation test"), wxDefaultPosition, parent->FromDIP(wxSize(-1, 280)), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), m_plater(plater)
|
||||
{
|
||||
wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
SetSizer(v_sizer);
|
||||
|
||||
// Model selection
|
||||
wxString m_rbModelChoices[] = { _L("Ringing Tower"), _L("Fast Tower") };
|
||||
int m_rbModelNChoices = sizeof(m_rbModelChoices) / sizeof(wxString);
|
||||
m_rbModel = new wxRadioBox(this, wxID_ANY, _L("Test model"), wxDefaultPosition, wxDefaultSize, m_rbModelNChoices, m_rbModelChoices, 1, wxRA_SPECIFY_ROWS);
|
||||
m_rbModel->SetSelection(1);
|
||||
v_sizer->Add(m_rbModel, 0, wxALL | wxEXPAND, 5);
|
||||
|
||||
// Settings
|
||||
wxString start_jd_str = _L("Start junction deviation: ");
|
||||
wxString end_jd_str = _L("End junction deviation: ");
|
||||
auto text_size = wxWindow::GetTextExtent(start_jd_str);
|
||||
text_size.IncTo(wxWindow::GetTextExtent(end_jd_str));
|
||||
text_size.x = text_size.x * 1.5;
|
||||
wxStaticBoxSizer* settings_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _L("Junction Deviation settings"));
|
||||
|
||||
auto st_size = FromDIP(wxSize(text_size.x, -1));
|
||||
auto ti_size = FromDIP(wxSize(90, -1));
|
||||
|
||||
// Start junction deviation
|
||||
auto start_jd_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto start_jd_text = new wxStaticText(this, wxID_ANY, start_jd_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiJDStart = new TextInput(this, wxString::Format("%.3f", 0.000), _L("mm"), "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiJDStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
start_jd_sizer->Add(start_jd_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
start_jd_sizer->Add(m_tiJDStart, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
settings_sizer->Add(start_jd_sizer);
|
||||
|
||||
// End junction deviation
|
||||
auto end_jd_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto end_jd_text = new wxStaticText(this, wxID_ANY, end_jd_str, wxDefaultPosition, st_size, wxALIGN_LEFT);
|
||||
m_tiJDEnd = new TextInput(this, wxString::Format("%.3f", 0.250), _L("mm"), "", wxDefaultPosition, ti_size, wxTE_CENTRE);
|
||||
m_tiJDEnd->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
end_jd_sizer->Add(end_jd_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
end_jd_sizer->Add(m_tiJDEnd, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
settings_sizer->Add(end_jd_sizer);
|
||||
|
||||
// Add note about junction deviation
|
||||
auto note_text = new wxStaticText(this, wxID_ANY, _L("Note: Lower values = sharper corners but slower speeds"),
|
||||
wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
note_text->SetForegroundColour(wxColour(128, 128, 128));
|
||||
settings_sizer->Add(note_text, 0, wxALL, 5);
|
||||
|
||||
v_sizer->Add(settings_sizer);
|
||||
v_sizer->Add(0, FromDIP(10), 0, wxEXPAND, 5);
|
||||
m_btnStart = new Button(this, _L("OK"));
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
|
||||
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
|
||||
|
||||
m_btnStart->SetBackgroundColor(btn_bg_green);
|
||||
m_btnStart->SetBorderColor(wxColour(0, 150, 136));
|
||||
m_btnStart->SetTextColor(wxColour("#FFFFFE"));
|
||||
m_btnStart->SetSize(wxSize(FromDIP(48), FromDIP(24)));
|
||||
m_btnStart->SetMinSize(wxSize(FromDIP(48), FromDIP(24)));
|
||||
m_btnStart->SetCornerRadius(FromDIP(3));
|
||||
m_btnStart->Bind(wxEVT_BUTTON, &Junction_Deviation_Test_Dlg::on_start, this);
|
||||
v_sizer->Add(m_btnStart, 0, wxALL | wxALIGN_RIGHT, FromDIP(5));
|
||||
|
||||
m_btnStart->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Junction_Deviation_Test_Dlg::on_start), NULL, this);
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
Junction_Deviation_Test_Dlg::~Junction_Deviation_Test_Dlg() {
|
||||
// Disconnect Events
|
||||
m_btnStart->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Junction_Deviation_Test_Dlg::on_start), NULL, this);
|
||||
}
|
||||
|
||||
void Junction_Deviation_Test_Dlg::on_start(wxCommandEvent& event) {
|
||||
bool read_double = false;
|
||||
read_double = m_tiJDStart->GetTextCtrl()->GetValue().ToDouble(&m_params.start);
|
||||
read_double = read_double && m_tiJDEnd->GetTextCtrl()->GetValue().ToDouble(&m_params.end);
|
||||
|
||||
if (!read_double || m_params.start < 0 || m_params.end >= 1 || m_params.start >= m_params.end) {
|
||||
MessageDialog msg_dlg(nullptr, _L("Please input valid values\n(0 <= Junction Deviation < 1)"), wxEmptyString, wxICON_WARNING | wxOK);
|
||||
msg_dlg.ShowModal();
|
||||
return;
|
||||
} 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;
|
||||
|
||||
// Set model type based on selection
|
||||
m_params.test_model = m_rbModel->GetSelection() == 0 ? 0 : 1; // 0 = Ringing Tower, 1 = Fast Tower
|
||||
|
||||
m_plater->calib_junction_deviation(m_params);
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void Junction_Deviation_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) {
|
||||
this->Refresh();
|
||||
Fit();
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
@@ -125,6 +125,65 @@ protected:
|
||||
Plater* m_plater;
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
class Input_Shaping_Freq_Test_Dlg : public DPIDialog
|
||||
{
|
||||
public:
|
||||
Input_Shaping_Freq_Test_Dlg (wxWindow* parent, wxWindowID id, Plater* plater);
|
||||
~Input_Shaping_Freq_Test_Dlg ();
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void on_start(wxCommandEvent& event);
|
||||
Calib_Params m_params;
|
||||
|
||||
wxRadioBox* m_rbModel;
|
||||
TextInput* m_tiFreqStartX;
|
||||
TextInput* m_tiFreqEndX;
|
||||
TextInput* m_tiFreqStartY;
|
||||
TextInput* m_tiFreqEndY;
|
||||
TextInput* m_tiDampingFactor;
|
||||
Button* m_btnStart;
|
||||
Plater* m_plater;
|
||||
};
|
||||
|
||||
class Input_Shaping_Damp_Test_Dlg : public DPIDialog
|
||||
{
|
||||
public:
|
||||
Input_Shaping_Damp_Test_Dlg (wxWindow* parent, wxWindowID id, Plater* plater);
|
||||
~Input_Shaping_Damp_Test_Dlg ();
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void on_start(wxCommandEvent& event);
|
||||
Calib_Params m_params;
|
||||
|
||||
wxRadioBox* m_rbModel;
|
||||
TextInput* m_tiFreqX;
|
||||
TextInput* m_tiFreqY;
|
||||
TextInput* m_tiDampingFactorStart;
|
||||
TextInput* m_tiDampingFactorEnd;
|
||||
Button* m_btnStart;
|
||||
Plater* m_plater;
|
||||
};
|
||||
|
||||
class Junction_Deviation_Test_Dlg : public DPIDialog
|
||||
{
|
||||
public:
|
||||
Junction_Deviation_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater);
|
||||
~Junction_Deviation_Test_Dlg();
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
|
||||
protected:
|
||||
virtual void on_start(wxCommandEvent& event);
|
||||
Calib_Params m_params;
|
||||
|
||||
wxRadioBox* m_rbModel;
|
||||
TextInput* m_tiJDStart;
|
||||
TextInput* m_tiJDEnd;
|
||||
Button* m_btnStart;
|
||||
Plater* m_plater;
|
||||
};
|
||||
}} // namespace Slic3r::GUI
|
||||
#endif
|
||||
|
||||
@@ -57,6 +57,12 @@ std::string get_calib_mode_name(CalibMode cali_mode, int stage)
|
||||
return "vfa_tower_calib_mode";
|
||||
case CalibMode::Calib_Retraction_tower:
|
||||
return "retration_tower_calib_mode";
|
||||
case CalibMode::Calib_Input_shaping_freq:
|
||||
return "input_shaping_freq_calib_mode";
|
||||
case CalibMode::Calib_Input_shaping_damp:
|
||||
return "input_shaping_damp_calib_mode";
|
||||
case CalibMode::Calib_Junction_Deviation:
|
||||
return "junction_deviation_calib_mode";
|
||||
default:
|
||||
assert(false);
|
||||
return "";
|
||||
@@ -196,6 +202,12 @@ CalibMode CalibUtils::get_calib_mode_by_name(const std::string name, int& cali_s
|
||||
return CalibMode::Calib_VFA_Tower;
|
||||
else if (name == "retration_tower_calib_mode")
|
||||
return CalibMode::Calib_Retraction_tower;
|
||||
else if (name == "input_shaping_freq_calib_mode")
|
||||
return CalibMode::Calib_Input_shaping_freq;
|
||||
else if (name == "input_shaping_damp_calib_mode")
|
||||
return CalibMode::Calib_Input_shaping_damp;
|
||||
else if (name == "junction_deviation_calib_mode")
|
||||
return CalibMode::Calib_Junction_Deviation;
|
||||
return CalibMode::Calib_None;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user