Juntion Deviation + Documentation

Junction Deviation Calibration Test
Base documentation
 - VFA
 - Input Shaping
 - Junction Deviation

Co-Authored-By: Rodrigo <162915171+rf47@users.noreply.github.com>
This commit is contained in:
Ian Bassi 2025-03-30 14:23:17 -03:00
parent 3662b5139c
commit 428cba9a25
13 changed files with 307 additions and 15 deletions

View file

@ -1,14 +1,18 @@
- [Flow rate](#Flow-rate) - [Flow rate](#flow-rate)
- [Pressure Advance](#Pressure-Advance) - [Pressure Advance](#pressure-advance)
1. [Line method](#Line-method) - [Line method](#line-method)
2. [Pattern method](#Pattern-method) - [Pattern method](#pattern-method)
3. [Tower method](#Tower-method) - [Tower method](#tower-method)
- [Temp tower](#Temp-tower) - [Temp tower](#temp-tower)
- [Retraction test](#Retraction-test) - [Retraction test](#retraction-test)
- [Orca Tolerance Test](#Orca-Tolerance-Test) - [Orca Tolerance Test](#orca-tolerance-test)
- [Advanced calibration](#Advanced-Calibration) - [Advanced Calibration](#advanced-calibration)
1. [Max Volumetric speed](#Max-Volumetric-speed) - [Max Volumetric speed](#max-volumetric-speed)
2. [VFA] - [Input Shaping](#input-shaping)
- [ZV Input Shaping](#zv-input-shaping)
- [Fixed-Time Motion](#fixed-time-motion)
- [Junction Deviation](#junction-deviation)
- [VFA](#vfa)
> [!IMPORTANT] > [!IMPORTANT]
> After completing the calibration process, remember to create a new project in order to exit the calibration mode. > After completing the calibration process, remember to create a new project in order to exit the calibration mode.
@ -152,6 +156,85 @@ You can also return to OrcaSlicer in the "Preview" tab, make sure the color sche
> [!NOTE] > [!NOTE]
> You may also choose to conservatively reduce the flow by 5-10% to ensure print quality. > You may also choose to conservatively reduce the flow by 5-10% to ensure print quality.
## Input Shaping
During high-speed movements, vibrations can cause a phenomenon called "ringing," where periodic ripples appear on the print surface. Input Shaping provides an effective solution by counteracting these vibrations, improving print quality and reducing wear on components without needing to significantly lower print speeds.
### ZV Input Shaping
ZV Input Shaping introduces an anti-vibration signal into the stepper motion for the X and Y axes. It works by splitting the step count into two halves: the first at half the frequency and the second as an "echo," delayed by half the ringing interval. This simple approach effectively reduces vibrations, improving print quality and allowing for higher speeds.
1. Pre-requisites:
1. In OrcaSlicer, set:
1. Acceleration high enough to trigger ringing (e.g., 2000 mm/s²).
2. Speed high enough to trigger ringing (e.g., 100 mm/s).
3. Jerk
1. If using a [Classic Jerk](https://marlinfw.org/docs/configuration/configuration.html#jerk-) use a high value (e.g., 20).
2. If using [Junction Deviation](https://marlinfw.org/docs/features/junction_deviation.html) this test will use 0.25 (high enough to most printers).
2. Use a high gloss filament to make the ringing more visible.
2. You need to print the Input SHaping Frequency test.
1. Measure the X and Y heights and read the frequency set at that point in Orca Slicer.
2. If not a clear result, you can measure a X and Y min and max acceptable heights and repeat the test with that min and max value.
3. When you find the best X and Y frequency, its time to Damp test setting your X and Y frequency to the value you found in the previous step.
4. Restore your 3D Printer settings to avoid keep using high acceleration and jerk values.
1. Reboot your printer.
2. Use the following G-code to restore your printer settings:
```gcode
M501
```
5. Save the settings
1. You need to go to the printer settings and set the X and Y frequency and damp to the value you found in the previous step.
2. Use the following G-code to set the frequency:
```gcode
M593 X F#Xfrequency D#XDamping
M593 Y F#Yfrequency D#YDamping
M500
```
Example
```gcode
M593 X F37.25 D0.16
M593 Y F37.5 D0.06
M500
```
### Fixed-Time Motion
TODO This calibration test is currently under development.
## Junction Deviation
Junction Deviation is the default method for controlling cornering speed in MarlinFW printers.
Higher values result in more aggressive cornering speeds, while lower values produce smoother, more controlled cornering.
The default value in Marlin is typically set to 0.08mm, which may be too high for some printers, potentially causing ringing. Consider lowering this value to reduce ringing, but avoid setting it too low, as this could lead to excessively slow cornering speeds.
1. Pre-requisites:
1. Check if your printer has Junction Deviation enabled. You can do this by sending the command `M503` to your printer and looking for the line `Junction deviation: 0.25`.
2. In OrcaSlicer, set:
1. Acceleration high enough to trigger ringing (e.g., 2000 mm/s²).
2. Speed high enough to trigger ringing (e.g., 100 mm/s).
3. Use a high gloss filament to make the ringing more visible.
2. You need to print the Junction Deviation test.
1. Measure the X and Y heights and read the frequency set at that point in Orca Slicer.
2. If not a clear result, you can measure a X and Y min and max acceptable heights and repeat the test with that min and max value.
3. Save the settings
1. Use the following G-code to set the frequency:
```gcode
M205 J#JunctionDeviationValue
M500
```
Example
```gcode
M205 J0.013
M500
```
2. Set it in your Marlin Compilation.
## VFA
Vertical Fine Artifacts (VFA) are small artifacts that can occur on the surface of a 3D print, particularly in areas where there are sharp corners or changes in direction. These artifacts can be caused by a variety of factors, including mechanical vibrations, resonance, and other factors that can affect the quality of the print.
Because of the nature of these artifacts the methods to reduce them can be mechanical such as changing motors, belts and pulleys or with advanced calibrations such as Jerk/[Juction Deviation](#junction-deviation) corrections or [Input Shaping](#input-shaping).
*** ***
*Credits:* *Credits:*
- *The Flowrate test and retraction test is inspired by [SuperSlicer](https://github.com/supermerill/SuperSlicer)* - *The Flowrate test and retraction test is inspired by [SuperSlicer](https://github.com/supermerill/SuperSlicer)*
@ -159,4 +242,5 @@ You can also return to OrcaSlicer in the "Preview" tab, make sure the color sche
- *The PA Tower method is inspired by [Klipper](https://www.klipper3d.org/Pressure_Advance.html)* - *The PA Tower method is inspired by [Klipper](https://www.klipper3d.org/Pressure_Advance.html)*
- *The temp tower model is remixed from [Smart compact temperature calibration tower](https://www.thingiverse.com/thing:2729076) - *The temp tower model is remixed from [Smart compact temperature calibration tower](https://www.thingiverse.com/thing:2729076)
- *The max flowrate test was inspired by Stefan(CNC Kitchen), and the model used in the test is a remix of his [Extrusion Test Structure](https://www.printables.com/model/342075-extrusion-test-structure). - *The max flowrate test was inspired by Stefan(CNC Kitchen), and the model used in the test is a remix of his [Extrusion Test Structure](https://www.printables.com/model/342075-extrusion-test-structure).
- *ZV Input Shaping is inspired by [Marlin Input Shaping](https://marlinfw.org/docs/features/input_shaping.html) and [Ringing Tower 3D STL](https://marlinfw.org/assets/stl/ringing_tower.stl)
- *ChatGPT* ;) - *ChatGPT* ;)

View file

@ -3749,7 +3749,6 @@ LayerResult GCode::process_layer(
//BBS: set layer time fan speed after layer change gcode //BBS: set layer time fan speed after layer change gcode
gcode += ";_SET_FAN_SPEED_CHANGING_LAYER\n"; gcode += ";_SET_FAN_SPEED_CHANGING_LAYER\n";
//TODO: Why this is not a Switch-case?
if (print.calib_mode() == CalibMode::Calib_PA_Tower) { 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); 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) { } else if (print.calib_mode() == CalibMode::Calib_Temp_Tower) {
@ -3770,9 +3769,13 @@ LayerResult GCode::process_layer(
gcode += buf; gcode += buf;
} else if (print.calib_mode() == CalibMode::Calib_Input_shaping_freq) { } else if (print.calib_mode() == CalibMode::Calib_Input_shaping_freq) {
if (m_layer_index == 1){ 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); gcode += writer().set_input_shaping('A', print.calib_params().start, 0.f);
} else { } else {
if (print.calib_params().freqStartX == print.calib_params().freqStartY && print.calib_params().freqEndX == print.calib_params().freqEndY) { if (print.calib_params().freqStartX == print.calib_params().freqStartY && print.calib_params().freqEndX == print.calib_params().freqEndY) {
gcode += writer().set_junction_deviation(0.25);
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 { } 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('X', 0.f, (print.calib_params().freqStartX) + ((print.calib_params().freqEndX)-(print.calib_params().freqStartX)) * (m_layer_index - 2) / (m_layer_count - 3));
@ -3781,11 +3784,16 @@ LayerResult GCode::process_layer(
} }
} else if (print.calib_mode() == CalibMode::Calib_Input_shaping_damp) { } else if (print.calib_mode() == CalibMode::Calib_Input_shaping_damp) {
if (m_layer_index == 1){ if (m_layer_index == 1){
gcode += writer().set_input_shaping('X', 0.f, print.calib_params().freqStartX); 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); gcode += writer().set_input_shaping('Y', 0.f, print.calib_params().freqStartY);
} else { } 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);
} }
} else if (print.calib_mode() == 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));
} }
//BBS //BBS

View file

@ -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::string GCodeWriter::set_pressure_advance(double pa) const
{ {
std::ostringstream gcode; std::ostringstream gcode;

View file

@ -53,6 +53,7 @@ public:
std::string set_jerk_xy(double jerk); std::string set_jerk_xy(double jerk);
// Orca: set acceleration and jerk in one command for Klipper // Orca: set acceleration and jerk in one command for Klipper
std::string set_accel_and_jerk(unsigned int acceleration, double jerk); 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_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) const;
std::string reset_e(bool force = false); std::string reset_e(bool force = false);

View file

@ -23,7 +23,8 @@ enum class CalibMode : int {
Calib_VFA_Tower, Calib_VFA_Tower,
Calib_Retraction_tower, Calib_Retraction_tower,
Calib_Input_shaping_freq, Calib_Input_shaping_freq,
Calib_Input_shaping_damp Calib_Input_shaping_damp,
Calib_Junction_Deviation
}; };
enum class CalibState { Start = 0, Preset, Calibration, CoarseSave, FineCalibration, Save, Finish }; enum class CalibState { Start = 0, Preset, Calibration, CoarseSave, FineCalibration, Save, Finish };

View file

@ -48,6 +48,8 @@ static wxString get_default_name(wxString filament_name, CalibMode mode){
break; break;
case Slic3r::CalibMode::Calib_Input_shaping_damp: case Slic3r::CalibMode::Calib_Input_shaping_damp:
break; break;
case Slic3r::CalibMode::Calib_Junction_Deviation:
break;
default: default:
break; break;
} }

View file

@ -3000,6 +3000,17 @@ void MainFrame::init_menubar_as_editor()
m_topbar->GetCalibMenu()->AppendSubMenu(input_shaping_menu, _L("Input Shaping")); 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...")); m_topbar->GetCalibMenu()->AppendSubMenu(advance_menu, _L("More..."));
// help // help
@ -3098,6 +3109,16 @@ void MainFrame::init_menubar_as_editor()
}, "", nullptr, }, "", nullptr,
[this]() {return m_plater->is_view3D_shown();; }, this); [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 // Input Shaping calibrations
auto input_shaping_menu = new wxMenu(); auto input_shaping_menu = new wxMenu();

View file

@ -356,6 +356,7 @@ public:
Retraction_Test_Dlg* m_retraction_calib_dlg{ nullptr }; Retraction_Test_Dlg* m_retraction_calib_dlg{ nullptr };
Input_Shaping_Freq_Test_Dlg* m_IS_freq_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 }; 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. // BBS. Replace title bar and menu bar with top bar.
BBLTopbar* m_topbar{ nullptr }; BBLTopbar* m_topbar{ nullptr };

View file

@ -10220,6 +10220,41 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params)
p->background_process.fff_print()->set_calib_params(params); 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 { 2.0 });
filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats { 200 });
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(); } BuildVolume_Type Plater::get_build_volume_type() const { return p->bed.get_build_volume_type(); }
void Plater::import_zip_archive() void Plater::import_zip_archive()

View file

@ -275,6 +275,7 @@ public:
void calib_VFA(const Calib_Params& params); void calib_VFA(const Calib_Params& params);
void calib_input_shaping_freq(const Calib_Params& params); void calib_input_shaping_freq(const Calib_Params& params);
void calib_input_shaping_damp(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; BuildVolume_Type get_build_volume_type() const;

View file

@ -1068,4 +1068,111 @@ void Input_Shaping_Damp_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) {
Fit(); Fit();
} }
}} // namespace Slic3r::GUI // 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

View file

@ -168,5 +168,22 @@ protected:
Plater* m_plater; 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 }} // namespace Slic3r::GUI
#endif #endif

View file

@ -61,6 +61,8 @@ std::string get_calib_mode_name(CalibMode cali_mode, int stage)
return "input_shaping_freq_calib_mode"; return "input_shaping_freq_calib_mode";
case CalibMode::Calib_Input_shaping_damp: case CalibMode::Calib_Input_shaping_damp:
return "input_shaping_damp_calib_mode"; return "input_shaping_damp_calib_mode";
case CalibMode::Calib_Junction_Deviation:
return "junction_deviation_calib_mode";
default: default:
assert(false); assert(false);
return ""; return "";
@ -204,6 +206,8 @@ CalibMode CalibUtils::get_calib_mode_by_name(const std::string name, int& cali_s
return CalibMode::Calib_Input_shaping_freq; return CalibMode::Calib_Input_shaping_freq;
else if (name == "input_shaping_damp_calib_mode") else if (name == "input_shaping_damp_calib_mode")
return CalibMode::Calib_Input_shaping_damp; return CalibMode::Calib_Input_shaping_damp;
else if (name == "junction_deviation_calib_mode")
return CalibMode::Calib_Junction_Deviation;
return CalibMode::Calib_None; return CalibMode::Calib_None;
} }