diff --git a/resources/calib/filament_flow/Orca-LinearFlow.3mf b/resources/calib/filament_flow/Orca-LinearFlow.3mf new file mode 100644 index 000000000..8be217beb Binary files /dev/null and b/resources/calib/filament_flow/Orca-LinearFlow.3mf differ diff --git a/resources/calib/filament_flow/Orca-LinearFlow_fine.3mf b/resources/calib/filament_flow/Orca-LinearFlow_fine.3mf new file mode 100644 index 000000000..94f8e62fb Binary files /dev/null and b/resources/calib/filament_flow/Orca-LinearFlow_fine.3mf differ diff --git a/resources/calib/filament_flow/flowrate-test-pass1.3mf b/resources/calib/filament_flow/flowrate-test-pass1.3mf index 8f1a1b5e6..20c997da0 100644 Binary files a/resources/calib/filament_flow/flowrate-test-pass1.3mf and b/resources/calib/filament_flow/flowrate-test-pass1.3mf differ diff --git a/resources/calib/filament_flow/flowrate-test-pass2.3mf b/resources/calib/filament_flow/flowrate-test-pass2.3mf index 4d1d0c369..979784940 100644 Binary files a/resources/calib/filament_flow/flowrate-test-pass2.3mf and b/resources/calib/filament_flow/flowrate-test-pass2.3mf differ diff --git a/resources/calib/filament_flow/pass1.3mf b/resources/calib/filament_flow/pass1.3mf new file mode 100644 index 000000000..794e53449 Binary files /dev/null and b/resources/calib/filament_flow/pass1.3mf differ diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 2f59daffb..47d7c30e8 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2822,10 +2822,17 @@ void MainFrame::init_menubar_as_editor() auto flowrate_menu = new wxMenu(); append_menu_item( flowrate_menu, wxID_ANY, _L("Pass 1"), _L("Flow rate test - Pass 1"), - [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(1); }, "", nullptr, + [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(false, 1); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); append_menu_item(flowrate_menu, wxID_ANY, _L("Pass 2"), _L("Flow rate test - Pass 2"), - [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(2); }, "", nullptr, + [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(false, 2); }, "", nullptr, + [this]() {return m_plater->is_view3D_shown();; }, this); + flowrate_menu->AppendSeparator(); + append_menu_item(flowrate_menu, wxID_ANY, _L("YOLO (Recommended)"), _L("Orca YOLO flowrate calibration, 0.01 step"), + [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(true, 1); }, "", nullptr, + [this]() {return m_plater->is_view3D_shown();; }, this); + append_menu_item(flowrate_menu, wxID_ANY, _L("YOLO (perfectionist version)"), _L("Orca YOLO flowrate calibration, 0.005 step"), + [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(true, 2); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); m_topbar->GetCalibMenu()->AppendSubMenu(flowrate_menu, _L("Flow rate")); append_menu_item(m_topbar->GetCalibMenu(), wxID_ANY, _L("Pressure advance"), _L("Pressure advance"), @@ -2909,13 +2916,20 @@ void MainFrame::init_menubar_as_editor() // Flowrate auto flowrate_menu = new wxMenu(); append_menu_item(flowrate_menu, wxID_ANY, _L("Pass 1"), _L("Flow rate test - Pass 1"), - [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(1); }, "", nullptr, + [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(false, 1); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); append_menu_item(flowrate_menu, wxID_ANY, _L("Pass 2"), _L("Flow rate test - Pass 2"), - [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(2); }, "", nullptr, + [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(false, 2); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); append_submenu(calib_menu,flowrate_menu,wxID_ANY,_L("Flow rate"),_L("Flow rate"),"", [this]() {return m_plater->is_view3D_shown();; }); + flowrate_menu->AppendSeparator(); + append_menu_item(flowrate_menu, wxID_ANY, _L("YOLO (Recommended)"), _L("Orca YOLO flowrate calibration, 0.01 step"), + [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(true, 1); }, "", nullptr, + [this]() {return m_plater->is_view3D_shown();; }, this); + append_menu_item(flowrate_menu, wxID_ANY, _L("YOLO (perfectionist version)"), _L("Orca YOLO flowrate calibration, 0.005 step"), + [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(true, 2); }, "", nullptr, + [this]() {return m_plater->is_view3D_shown();; }, this); // PA append_menu_item(calib_menu, wxID_ANY, _L("Pressure advance"), _L("Pressure advance"), diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7950f9a66..469bba911 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -9646,21 +9646,11 @@ void Plater::_calib_pa_select_added_objects() { } } -void Plater::calib_flowrate(int pass) { - if (pass != 1 && pass != 2) - return; - const auto calib_name = wxString::Format(L"Flowrate Test - Pass%d", pass); - if (new_project(false, false, calib_name) == wxID_CANCEL) - return; - - wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); - - if(pass == 1) - add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass1.3mf").string()); - else - add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass2.3mf").string()); - - auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; +// Adjust settings for flowrate calibration +// For linear mode, pass 1 means normal version while pass 2 mean "for perfectionists" version +void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, int pass) +{ +auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto printerConfig = &wxGetApp().preset_bundle->printers.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; @@ -9670,37 +9660,47 @@ void Plater::calib_flowrate(int pass) { assert(nozzle_diameter_config->values.size() > 0); float nozzle_diameter = nozzle_diameter_config->values[0]; float xyScale = nozzle_diameter / 0.6; - //scale z to have 7 layers + //scale z to have 10 layers + // 2 bottom, 5 top, 3 sparse infill double first_layer_height = print_config->option("initial_layer_print_height")->value; double layer_height = nozzle_diameter / 2.0; // prefer 0.2 layer height for 0.4 nozzle first_layer_height = std::max(first_layer_height, layer_height); - float zscale = (first_layer_height + 6 * layer_height) / 1.4; + float zscale = (first_layer_height + 9 * layer_height) / 2; // only enlarge if (xyScale > 1.2) { - for (auto _obj : model().objects) + for (auto _obj : objects) _obj->scale(xyScale, xyScale, zscale); } else { - for (auto _obj : model().objects) + for (auto _obj : objects) _obj->scale(1, 1, zscale); } + auto cur_flowrate = filament_config->option("filament_flow_ratio")->get_at(0); Flow infill_flow = Flow(nozzle_diameter * 1.2f, layer_height, nozzle_diameter); double filament_max_volumetric_speed = filament_config->option("filament_max_volumetric_speed")->get_at(0); - double max_infill_speed = filament_max_volumetric_speed / (infill_flow.mm3_per_mm() * (pass == 1 ? 1.2 : 1)); + double max_infill_speed; + if (linear) + max_infill_speed = filament_max_volumetric_speed / + (infill_flow.mm3_per_mm() * (cur_flowrate + (pass == 2 ? 0.035 : 0.05)) / cur_flowrate); + else + max_infill_speed = filament_max_volumetric_speed / (infill_flow.mm3_per_mm() * (pass == 1 ? 1.2 : 1)); double internal_solid_speed = std::floor(std::min(print_config->opt_float("internal_solid_infill_speed"), max_infill_speed)); double top_surface_speed = std::floor(std::min(print_config->opt_float("top_surface_speed"), max_infill_speed)); // adjust parameters - for (auto _obj : model().objects) { + for (auto _obj : objects) { _obj->ensure_on_bed(); - _obj->config.set_key_value("wall_loops", new ConfigOptionInt(3)); + _obj->config.set_key_value("wall_loops", new ConfigOptionInt(1)); _obj->config.set_key_value("only_one_wall_top", new ConfigOptionBool(true)); + _obj->config.set_key_value("thick_internal_bridges", new ConfigOptionBool(false)); _obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(35)); _obj->config.set_key_value("min_width_top_surface", new ConfigOptionFloatOrPercent(100,true)); - _obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(1)); + _obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(2)); _obj->config.set_key_value("top_shell_layers", new ConfigOptionInt(5)); + _obj->config.set_key_value("top_shell_thickness", new ConfigOptionFloat(0)); + _obj->config.set_key_value("bottom_shell_thickness", new ConfigOptionFloat(0)); _obj->config.set_key_value("detect_thin_wall", new ConfigOptionBool(true)); _obj->config.set_key_value("filter_out_gap_fill", new ConfigOptionFloat(0)); _obj->config.set_key_value("sparse_infill_pattern", new ConfigOptionEnum(ipRectilinear)); @@ -9724,14 +9724,18 @@ void Plater::calib_flowrate(int pass) { if (obj_name[0] == 'm') obj_name[0] = '-'; auto modifier = stof(obj_name); - _obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f + modifier/100.f)); + if(linear) + _obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat((cur_flowrate + modifier)/cur_flowrate)); + else + _obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f + modifier/100.f)); + } print_config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); print_config->set_key_value("initial_layer_print_height", new ConfigOptionFloat(first_layer_height)); print_config->set_key_value("reduce_crossing_wall", new ConfigOptionBool(true)); - //filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{ 9. }); + wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); @@ -9741,6 +9745,43 @@ void Plater::calib_flowrate(int pass) { wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); } +void Plater::calib_flowrate(bool is_linear, int pass) { + if (pass != 1 && pass != 2) + return; + wxString calib_name; + if (is_linear) { + calib_name = L"Orca YOLO Flow Calibration"; + if (pass == 2) + calib_name += L" - Perfectionist version"; + } else + calib_name = wxString::Format(L"Flowrate Test - Pass%d", pass); + + if (new_project(false, false, calib_name) == wxID_CANCEL) + return; + + wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); + + if (is_linear) { + if (pass == 1) + add_model(false, + (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "Orca-LinearFlow.3mf").string()); + else + add_model(false, + (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "Orca-LinearFlow_fine.3mf").string()); + } else { + if (pass == 1) + add_model(false, + (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass1.3mf").string()); + else + add_model(false, + (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass2.3mf").string()); + } + + adjust_settings_for_flowrate_calib(model().objects, is_linear, pass); + wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); +} + + void Plater::calib_temp(const Calib_Params& params) { const auto calib_temp_name = wxString::Format(L"Nozzle temperature test"); new_project(false, false, calib_temp_name); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 16396631a..109e7845d 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -259,7 +259,7 @@ public: // SoftFever void calib_pa(const Calib_Params& params); - void calib_flowrate(int pass); + void calib_flowrate(bool is_linear, int pass); void calib_temp(const Calib_Params& params); void calib_max_vol_speed(const Calib_Params& params); void calib_retraction(const Calib_Params& params);