From e51c6a2e649eefa24dc1af507330b38ab47f725a Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Thu, 16 Oct 2025 21:00:48 +0300 Subject: [PATCH 01/19] GoldenRatio Flow Calibration Test --- .../filament_flow/golden-ratio-flow-test.3mf | Bin 0 -> 24159 bytes src/libslic3r/Fill/FillBase.cpp | 37 ++++++++- src/libslic3r/Fill/FillPlanePath.cpp | 4 +- src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 8 +- src/libslic3r/PrintConfig.hpp | 8 +- src/slic3r/GUI/MainFrame.cpp | 4 + src/slic3r/GUI/Plater.cpp | 77 +++++++++++++++++- src/slic3r/GUI/Plater.hpp | 1 + 9 files changed, 129 insertions(+), 12 deletions(-) create mode 100644 resources/calib/filament_flow/golden-ratio-flow-test.3mf diff --git a/resources/calib/filament_flow/golden-ratio-flow-test.3mf b/resources/calib/filament_flow/golden-ratio-flow-test.3mf new file mode 100644 index 0000000000000000000000000000000000000000..25f72b994fdbd3806866b6005d713fda7227aa8a GIT binary patch literal 24159 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 literal 0 HcmV?d00001 diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index f7c003cb2f..f5a7157632 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -162,8 +162,8 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para // Only concentric fills are not sorted. eec->no_sort = this->no_sort(); // ORCA: special flag for flow rate calibration - auto is_flow_calib = params.extrusion_role == erTopSolidInfill && this->print_object_config->has("calib_flowrate_topinfill_special_order") && - this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool(); + auto is_flow_calib = params.extrusion_role == erTopSolidInfill && this->print_object_config->has("calib_test_mode") && + (this->print_object_config->calib_test_mode.value == CalibTestMode::CalibFlowrateTopInfillSpecialOrder); if (is_flow_calib) { eec->no_sort = true; } @@ -179,6 +179,39 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para params.extrusion_role, flow_mm3_per_mm, float(flow_width), params.flow.height()); } + + switch (this->print_object_config->calib_test_mode.value) { + case CalibTestMode::GoldenRatioFlowTest: + eec->no_sort = true; + eec->reverse(); + if (layer_id > 1) { + double _wmin = 0.9; + double _wmax = 1.1; + double _wlen = _wmax - _wmin; + BoundingBox _bbox = this->bounding_box; + coord_t _width = _bbox.size().x(); + coord_t _semiwidth = _width / 2; + coord_t _xmin = _bbox.center().x() - _semiwidth; + coord_t _xmax = _bbox.center().x() + _semiwidth; + + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + coord_t _x = _p->polyline.points.front().x(); + double _q = _wlen * (_x - _xmin) / _width + _wmin; + _p->width *= _q; + _p->mm3_per_mm *= _q; + if (_p->polyline.points.front().y() > _p->polyline.points.back().y()) + _p->reverse(); + } + } + else if (layer_id == 1) + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + _p->width *= 0.8; + _p->mm3_per_mm *= 0.8; + } + break; + } if (!params.can_reverse || is_flow_calib) { for (size_t i = idx; i < eec->entities.size(); i++) eec->entities[i]->set_reverse(); diff --git a/src/libslic3r/Fill/FillPlanePath.cpp b/src/libslic3r/Fill/FillPlanePath.cpp index 6044ba43a2..131f9e6b3c 100644 --- a/src/libslic3r/Fill/FillPlanePath.cpp +++ b/src/libslic3r/Fill/FillPlanePath.cpp @@ -124,8 +124,8 @@ void FillPlanePath::_fill_surface_single( if (params.dont_connect() || params.density > 0.5) { // ORCA: special flag for flow rate calibration auto is_flow_calib = params.extrusion_role == erTopSolidInfill && - this->print_object_config->has("calib_flowrate_topinfill_special_order") && - this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool() && + this->print_object_config->has("calib_test_mode") && + (this->print_object_config->calib_test_mode.value == CalibTestMode::CalibFlowrateTopInfillSpecialOrder) && dynamic_cast(this); if (is_flow_calib) { // We want the spiral part to be printed inside-out diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 6718e0e809..0a71daea69 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -847,7 +847,7 @@ static std::vector s_Preset_print_options { "hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth", "small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model", "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "scarf_joint_flow_ratio", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", "scarf_overhang_threshold", - "interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width","calib_flowrate_topinfill_special_order", + "interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width", "calib_test_mode", }; static std::vector s_Preset_filament_options { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 498678ad29..5a85ceafc6 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3451,10 +3451,10 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionInt(2)); - // ORCA: special flag for flow rate calibration - def = this->add("calib_flowrate_topinfill_special_order", coBool); - def->mode = comDevelop; - def->set_default_value(new ConfigOptionBool(false)); + // ORCA: special flag for calibration tests + def = this->add("calib_test_mode", coInt); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionInt(CalibTestMode::None)); def = this->add("ironing_type", coEnum); def->label = L("Ironing Type"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 1e927a1a13..f54e2f0b89 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -34,6 +34,11 @@ enum GCodeFlavor : unsigned char { gcfSmoothie, gcfNoExtrusion }; +enum CalibTestMode { + None, + GoldenRatioFlowTest, + CalibFlowrateTopInfillSpecialOrder, +}; enum class FuzzySkinType { None, @@ -948,8 +953,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionInt, interlocking_boundary_avoidance)) // Orca: internal use only - ((ConfigOptionBool, calib_flowrate_topinfill_special_order)) // ORCA: special flag for flow rate calibration - + ((ConfigOptionInt, calib_test_mode)) // ORCA: special flag for calibration tests ) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index df1dc541c4..75389a0753 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2927,6 +2927,10 @@ void MainFrame::init_menubar_as_editor() 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); + flowrate_menu->AppendSeparator(); + append_menu_item(flowrate_menu, wxID_ANY, _L("GoldenRatio Flow Test"), _L("GoldenRatio Flow calibration test 90-110%"), + [this](wxCommandEvent&) { if (m_plater) m_plater->calib_golden_ratio_flow(true, 1); }, "", nullptr, + [this]() {return m_plater->is_view3D_shown();; }, this); m_topbar->GetCalibMenu()->AppendSubMenu(flowrate_menu, _L("Flow rate")); // Pressure Advance diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d9c95d6d06..15161e4e6a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -9856,6 +9856,81 @@ void Plater::_calib_pa_select_added_objects() { } } +// Adjust settings for golden ratio flow calibration +void adjust_settings_for_golden_ratio_flow_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; + + const ConfigOptionFloats* nozzle_diameter_config = printerConfig->option("nozzle_diameter"); + assert(nozzle_diameter_config->values.size() > 0); + float nozzle_diameter = nozzle_diameter_config->values[0]; + // 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); + + // adjust parameters + for (auto _obj : objects) { + _obj->ensure_on_bed(); + _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("enable_extra_bridge_layer", new ConfigOptionEnum(eblDisabled)); + _obj->config.set_key_value("internal_bridge_density", new ConfigOptionPercent(100)); + _obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(100)); + _obj->config.set_key_value("min_width_top_surface", new ConfigOptionFloatOrPercent(100, true)); + _obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(2)); + _obj->config.set_key_value("top_shell_layers", new ConfigOptionInt(0)); + _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(ipMonotonicLine)); + _obj->config.set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); + _obj->config.set_key_value("top_surface_pattern", new ConfigOptionEnum(ipMonotonicLine)); + _obj->config.set_key_value("bottom_surface_pattern", new ConfigOptionEnum(ipMonotonic)); + _obj->config.set_key_value("bottom_surface_density", new ConfigOptionPercent(90)); + _obj->config.set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f)); + _obj->config.set_key_value("infill_direction", new ConfigOptionFloat(0)); + _obj->config.set_key_value("internal_solid_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); + _obj->config.set_key_value("solid_infill_direction", new ConfigOptionFloat(0)); + _obj->config.set_key_value("solid_infill_rotate_template", new ConfigOptionString("90, 0, 90#100")); + _obj->config.set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true)); + _obj->config.set_key_value("ironing_type", new ConfigOptionEnum(IroningType::NoIroning)); + _obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(30)); //internal_solid_speed + _obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); + _obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); + _obj->config.set_key_value("calib_test_mode", new ConfigOptionInt(CalibTestMode::GoldenRatioFlowTest)); + print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); + _obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f)); + _obj->name = "GoldenRatio Flow Calibration Test 90-110%"; + } + + 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)); + + wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); + wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); + wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty(); + wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config(); + wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config(); + wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); +} + +void Plater::calib_golden_ratio_flow(bool is_linear, int pass) { + wxString calib_name = L"GoldenRatio Flow Calibration Test 90-110%"; + if (new_project(false, false, calib_name) == wxID_CANCEL) + return; + + wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); + add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "golden-ratio-flow-test.3mf").string()); + adjust_settings_for_golden_ratio_flow_calib(model().objects, is_linear, pass); +} + // 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) @@ -9932,7 +10007,7 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i _obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); _obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); - _obj->config.set_key_value("calib_flowrate_topinfill_special_order", new ConfigOptionBool(true)); + _obj->config.set_key_value("calib_test_mode", new ConfigOptionInt(CalibTestMode::CalibFlowrateTopInfillSpecialOrder)); // extract flowrate from name, filename format: flowrate_xxx std::string obj_name = _obj->name; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index ece34ba829..4d059e6b1b 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -268,6 +268,7 @@ public: // SoftFever void calib_pa(const Calib_Params& params); + void calib_golden_ratio_flow(bool is_linear, 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); From 51e096c83246afce8bcceef0ded842aa175ee9a9 Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Mon, 27 Oct 2025 23:09:23 +0300 Subject: [PATCH 02/19] Add menu and some usabilities --- src/libslic3r/Fill/Fill.cpp | 1 + src/libslic3r/Fill/FillBase.cpp | 107 +++++++++------ src/libslic3r/Fill/FillBase.hpp | 2 + src/libslic3r/Fill/FillPlanePath.cpp | 2 +- src/libslic3r/Model.cpp | 4 + src/libslic3r/Model.hpp | 1 + src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 5 - src/libslic3r/PrintConfig.hpp | 10 -- src/libslic3r/calib.hpp | 7 +- src/slic3r/GUI/MainFrame.cpp | 8 +- src/slic3r/GUI/MainFrame.hpp | 1 + src/slic3r/GUI/Plater.cpp | 98 ++++++++------ src/slic3r/GUI/Plater.hpp | 1 + src/slic3r/GUI/calib_dlg.cpp | 190 +++++++++++++++++++++++++++ src/slic3r/GUI/calib_dlg.hpp | 25 ++++ 16 files changed, 364 insertions(+), 100 deletions(-) diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index e8294ea673..c409cdf6f2 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -1202,6 +1202,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree; f->print_config = &this->object()->print()->config(); f->print_object_config = &this->object()->config(); + f->calib_params = &this->object()->model_object()->get_model()->calib_params; if (surface_fill.params.pattern == ipConcentricInternal) { FillConcentricInternal *fill_concentric = dynamic_cast(f.get()); assert(fill_concentric != nullptr); diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index f5a7157632..8f20d2c995 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -11,6 +11,7 @@ #include "../Surface.hpp" #include "../libslic3r.h" #include "../VariableWidth.hpp" +#include "../calib.hpp" #include "FillBase.hpp" #include "FillConcentric.hpp" @@ -161,12 +162,21 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para out.push_back(eec = new ExtrusionEntityCollection()); // Only concentric fills are not sorted. eec->no_sort = this->no_sort(); - // ORCA: special flag for flow rate calibration - auto is_flow_calib = params.extrusion_role == erTopSolidInfill && this->print_object_config->has("calib_test_mode") && - (this->print_object_config->calib_test_mode.value == CalibTestMode::CalibFlowrateTopInfillSpecialOrder); - if (is_flow_calib) { - eec->no_sort = true; + + // Calibration section (pre-extrusion) + if (calib_params != nullptr) { + switch (calib_params->mode) { + case CalibMode::Calib_Flow_Rate: + if (params.extrusion_role == erTopSolidInfill) { + eec->no_sort = true; + break; + } + case CalibMode::Calib_Golden_Ratio_Flow: + eec->no_sort = true; + } } + + // Extrusion section size_t idx = eec->entities.size(); if (params.use_arachne) { Flow new_flow = params.flow.with_spacing(float(this->spacing)); @@ -180,45 +190,62 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para flow_mm3_per_mm, float(flow_width), params.flow.height()); } - switch (this->print_object_config->calib_test_mode.value) { - case CalibTestMode::GoldenRatioFlowTest: - eec->no_sort = true; - eec->reverse(); - if (layer_id > 1) { - double _wmin = 0.9; - double _wmax = 1.1; - double _wlen = _wmax - _wmin; - BoundingBox _bbox = this->bounding_box; - coord_t _width = _bbox.size().x(); - coord_t _semiwidth = _width / 2; - coord_t _xmin = _bbox.center().x() - _semiwidth; - coord_t _xmax = _bbox.center().x() + _semiwidth; - - for (ExtrusionEntity* e : eec->entities) { - ExtrusionPath* _p = static_cast(e); - coord_t _x = _p->polyline.points.front().x(); - double _q = _wlen * (_x - _xmin) / _width + _wmin; - _p->width *= _q; - _p->mm3_per_mm *= _q; - if (_p->polyline.points.front().y() > _p->polyline.points.back().y()) - _p->reverse(); + // Calibration section (post-extrusion) with sended parameters + if (calib_params != nullptr) { + switch (calib_params->mode) { + case CalibMode::Calib_Flow_Rate: + for (size_t i = idx; i < eec->entities.size(); i++) { + eec->entities[i]->set_reverse(); } + break; + case CalibMode::Calib_Golden_Ratio_Flow: + eec->reverse(); + if (layer_id > 1) { + double _wmin = this->calib_params->start; + double _wmax = this->calib_params->end; + double _wlen = _wmax - _wmin; + BoundingBox _bbox = this->bounding_box; + coord_t _width = _bbox.size().x(); + coord_t _semiwidth = _width / 2; + coord_t _xmin = _bbox.center().x() - _semiwidth; + coord_t _xmax = _bbox.center().x() + _semiwidth; + + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + coord_t _x = _p->polyline.points.front().x(); + double _q = _wlen * (_x - _xmin) / _width + _wmin; + _p->width *= _q; + _p->mm3_per_mm *= _q; + if (_p->polyline.points.front().y() > _p->polyline.points.back().y()) + _p->reverse(); + } + if (calib_params->interlaced) { // Inrtleaced sort + std::vector a, b; + int _i = 0; + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + if (++_i % 2) + a.emplace_back(_p); + else + b.emplace_back(_p); + } + eec->entities.clear(); + for (ExtrusionPath* _p : a) + eec->entities.emplace_back(_p); + for (ExtrusionPath* _p : b) + eec->entities.emplace_back(_p); + } + } else if (layer_id == 1) + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + _p->width *= 0.75; + _p->mm3_per_mm *= 0.75; + } } - else if (layer_id == 1) - for (ExtrusionEntity* e : eec->entities) { - ExtrusionPath* _p = static_cast(e); - _p->width *= 0.8; - _p->mm3_per_mm *= 0.8; - } - break; - } - if (!params.can_reverse || is_flow_calib) { - for (size_t i = idx; i < eec->entities.size(); i++) - eec->entities[i]->set_reverse(); - } - + } else { // Orca: run gap fill this->_create_gap_fill(surface, params, eec); + } } } diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 5e1b6d5445..82124eed50 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -20,6 +20,7 @@ #include "../ExtrusionEntity.hpp" #include "../ExtrusionEntityCollection.hpp" #include "../ShortestPath.hpp" +#include "../calib.hpp" namespace Slic3r { @@ -137,6 +138,7 @@ public: // Orca: also used by gap fill function. const PrintConfig *print_config = nullptr; const PrintObjectConfig *print_object_config = nullptr; + const Calib_Params *calib_params = nullptr; // BBS: all no overlap expolygons in same layer ExPolygons no_overlap_expolygons; diff --git a/src/libslic3r/Fill/FillPlanePath.cpp b/src/libslic3r/Fill/FillPlanePath.cpp index 131f9e6b3c..559efc5c9d 100644 --- a/src/libslic3r/Fill/FillPlanePath.cpp +++ b/src/libslic3r/Fill/FillPlanePath.cpp @@ -125,7 +125,7 @@ void FillPlanePath::_fill_surface_single( // ORCA: special flag for flow rate calibration auto is_flow_calib = params.extrusion_role == erTopSolidInfill && this->print_object_config->has("calib_test_mode") && - (this->print_object_config->calib_test_mode.value == CalibTestMode::CalibFlowrateTopInfillSpecialOrder) && + (calib_params->mode == CalibMode::Calib_Flow_Rate) && dynamic_cast(this); if (is_flow_calib) { // We want the spiral part to be printed inside-out diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 4edec076af..d9319aca55 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -88,6 +88,8 @@ Model& Model::assign_copy(const Model &rhs) this->calib_pa_pattern = std::make_unique(CalibPressureAdvancePattern(*rhs.calib_pa_pattern)); } + this->calib_params = rhs.calib_params; + // BBS: for design info this->design_info = rhs.design_info; this->model_info = rhs.model_info; @@ -126,6 +128,8 @@ Model& Model::assign_copy(Model &&rhs) this->calib_pa_pattern.reset(); this->calib_pa_pattern.swap(rhs.calib_pa_pattern); + this->calib_params = rhs.calib_params; + //BBS: add auxiliary path logic // BBS: backup, all in one temp dir this->stl_design_id = rhs.stl_design_id; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 0456448e65..f30d7ffaf7 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1684,6 +1684,7 @@ public: bool is_fuzzy_skin_painted() const; std::unique_ptr calib_pa_pattern; + Calib_Params calib_params; private: explicit Model(int) : ObjectBase(-1) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 0a71daea69..eef453eb29 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -847,7 +847,7 @@ static std::vector s_Preset_print_options { "hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth", "small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model", "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "scarf_joint_flow_ratio", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", "scarf_overhang_threshold", - "interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width", "calib_test_mode", + "interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width", }; static std::vector s_Preset_filament_options { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 5a85ceafc6..e99abf7a87 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3451,11 +3451,6 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionInt(2)); - // ORCA: special flag for calibration tests - def = this->add("calib_test_mode", coInt); - def->mode = comDevelop; - def->set_default_value(new ConfigOptionInt(CalibTestMode::None)); - def = this->add("ironing_type", coEnum); def->label = L("Ironing Type"); def->category = L("Quality"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index f54e2f0b89..f2d35652c6 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -34,12 +34,6 @@ enum GCodeFlavor : unsigned char { gcfSmoothie, gcfNoExtrusion }; -enum CalibTestMode { - None, - GoldenRatioFlowTest, - CalibFlowrateTopInfillSpecialOrder, -}; - enum class FuzzySkinType { None, External, @@ -951,10 +945,6 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionInt, interlocking_beam_layer_count)) ((ConfigOptionInt, interlocking_depth)) ((ConfigOptionInt, interlocking_boundary_avoidance)) - - // Orca: internal use only - ((ConfigOptionInt, calib_test_mode)) // ORCA: special flag for calibration tests - ) // This object is mapped to Perl as Slic3r::Config::PrintRegion. diff --git a/src/libslic3r/calib.hpp b/src/libslic3r/calib.hpp index d7db10fd81..c5bdeede97 100644 --- a/src/libslic3r/calib.hpp +++ b/src/libslic3r/calib.hpp @@ -24,7 +24,8 @@ enum class CalibMode : int { Calib_Retraction_tower, Calib_Input_shaping_freq, Calib_Input_shaping_damp, - Calib_Junction_Deviation + Calib_Junction_Deviation, + Calib_Golden_Ratio_Flow, }; enum class CalibState { Start = 0, Preset, Calibration, CoarseSave, FineCalibration, Save, Finish }; @@ -34,9 +35,9 @@ struct Calib_Params Calib_Params() : mode(CalibMode::Calib_None){}; int extruder_id = 0; double start, end, step; - bool print_numbers; + bool print_numbers, use_zhop, interlaced; double freqStartX, freqEndX, freqStartY, freqEndY; - int test_model; + int test_model, model_variant; std::vector accelerations; std::vector speeds; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 75389a0753..c90ad561b9 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2928,9 +2928,13 @@ void MainFrame::init_menubar_as_editor() [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(true, 2); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); flowrate_menu->AppendSeparator(); + //append_menu_item(flowrate_menu, wxID_ANY, _L("GoldenRatio Flow Test"), _L("GoldenRatio Flow calibration test 90-110%"), + // [this](wxCommandEvent&) { if (m_plater) m_plater->calib_golden_ratio_flow(true, 1); }, "", nullptr, + // [this]() {return m_plater->is_view3D_shown();; }, this); append_menu_item(flowrate_menu, wxID_ANY, _L("GoldenRatio Flow Test"), _L("GoldenRatio Flow calibration test 90-110%"), - [this](wxCommandEvent&) { if (m_plater) m_plater->calib_golden_ratio_flow(true, 1); }, "", nullptr, - [this]() {return m_plater->is_view3D_shown();; }, this); + [this](wxCommandEvent&) { if (!m_golden_ratio_flow_calib_dlg) + m_golden_ratio_flow_calib_dlg = new GoldenRatio_Flow_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater); + m_golden_ratio_flow_calib_dlg->ShowModal();}, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); m_topbar->GetCalibMenu()->AppendSubMenu(flowrate_menu, _L("Flow rate")); // Pressure Advance diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 410ea8dc62..62d005d3fa 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -357,6 +357,7 @@ public: 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 }; + GoldenRatio_Flow_Test_Dlg* m_golden_ratio_flow_calib_dlg{ nullptr }; // BBS. Replace title bar and menu bar with top bar. BBLTopbar* m_topbar{ nullptr }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 15161e4e6a..589e14b16a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -9857,78 +9857,99 @@ void Plater::_calib_pa_select_added_objects() { } // Adjust settings for golden ratio flow calibration -void adjust_settings_for_golden_ratio_flow_calib(ModelObjectPtrs& objects, bool linear, int pass) { +void Plater::calib_golden_ratio_flow(const Calib_Params& params) { + wxString calib_name = L"GoldenRatio Flow Test"; + if (new_project(false, false, calib_name) == wxID_CANCEL) + return; + wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); + add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "golden-ratio-flow-test.3mf").string()); + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; - auto printerConfig = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; - const ConfigOptionFloats* nozzle_diameter_config = printerConfig->option("nozzle_diameter"); + /// --- scale --- + // model is created for a 0.4 nozzle, scale z with nozzle size. + const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter"); assert(nozzle_diameter_config->values.size() > 0); float nozzle_diameter = nozzle_diameter_config->values[0]; - // scale z to have 10 layers - // 2 bottom, 5 top, 3 sparse infill + // scale z to have 6 layers 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); + const auto canvas = wxGetApp().plater()->canvas3D(); + auto& selection = canvas->get_selection(); + selection.setup_cache(); + TransformationType transformation_type; + transformation_type.set_relative(); + float const calib_scale[3] = {1.0f, 1.5f, 2.0f}; + float zscale = (first_layer_height + 5 * layer_height) / 1.2; + float xscale = calib_scale[params.test_model]; + float yscale = calib_scale[params.model_variant]; + + // only enlarge + selection.scale({xscale, yscale, zscale}, transformation_type); + canvas->do_scale(""); + model().calib_params = params; + // adjust parameters - for (auto _obj : objects) { + for (auto _obj : model().objects) { _obj->ensure_on_bed(); _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("internal_bridge_density", new ConfigOptionPercent(100)); _obj->config.set_key_value("thick_internal_bridges", new ConfigOptionBool(false)); _obj->config.set_key_value("enable_extra_bridge_layer", new ConfigOptionEnum(eblDisabled)); - _obj->config.set_key_value("internal_bridge_density", new ConfigOptionPercent(100)); - _obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(100)); _obj->config.set_key_value("min_width_top_surface", new ConfigOptionFloatOrPercent(100, true)); - _obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(2)); + _obj->config.set_key_value("only_one_wall_top", new ConfigOptionBool(true)); + _obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f)); _obj->config.set_key_value("top_shell_layers", new ConfigOptionInt(0)); - _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(ipMonotonicLine)); - _obj->config.set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); _obj->config.set_key_value("top_surface_pattern", new ConfigOptionEnum(ipMonotonicLine)); - _obj->config.set_key_value("bottom_surface_pattern", new ConfigOptionEnum(ipMonotonic)); - _obj->config.set_key_value("bottom_surface_density", new ConfigOptionPercent(90)); _obj->config.set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f)); - _obj->config.set_key_value("infill_direction", new ConfigOptionFloat(0)); - _obj->config.set_key_value("internal_solid_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); + _obj->config.set_key_value("top_shell_thickness", new ConfigOptionFloat(0)); + _obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(2)); + _obj->config.set_key_value("bottom_surface_pattern", new ConfigOptionEnum(ipMonotonic)); + _obj->config.set_key_value("bottom_shell_thickness", new ConfigOptionFloat(0)); + _obj->config.set_key_value("bottom_surface_density", new ConfigOptionPercent(90)); + _obj->config.set_key_value("sparse_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); + _obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(100)); _obj->config.set_key_value("solid_infill_direction", new ConfigOptionFloat(0)); _obj->config.set_key_value("solid_infill_rotate_template", new ConfigOptionString("90, 0, 90#100")); + _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("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); + _obj->config.set_key_value("infill_direction", new ConfigOptionFloat(0)); + _obj->config.set_key_value("internal_solid_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); _obj->config.set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true)); _obj->config.set_key_value("ironing_type", new ConfigOptionEnum(IroningType::NoIroning)); - _obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(30)); //internal_solid_speed + _obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed _obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); _obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); - _obj->config.set_key_value("calib_test_mode", new ConfigOptionInt(CalibTestMode::GoldenRatioFlowTest)); - print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); - _obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f)); - _obj->name = "GoldenRatio Flow Calibration Test 90-110%"; + _obj->name = format("GoldenRatio_Flow_Test_%.2f~%.2f_@%fmmps", params.start, params.end, params.speeds[0]); } + print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); 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("alternate_extra_wall", new ConfigOptionBool(false)); print_config->set_key_value("reduce_crossing_wall", new ConfigOptionBool(true)); + printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{RetractLiftEnforceType::rletAllSurfaces}); + printer_config->set_key_value("z_hop", new ConfigOptionFloats{params.use_zhop ? 1.0f : 0.0f}); + printer_config->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtNormal}); + printer_config->set_key_value("wipe_distance", new ConfigOptionFloats{0.0f}); + + // filament_config->set_key_value("filament_retract_lift_enforce", new ConfigOptionEnumsGeneric{RetractLiftEnforceType::rletAllSurfaces}); + // filament_config->set_key_value("filament_z_hop", new ConfigOptionFloats{0.0f}); + // filament_config->set_key_value("filament_z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtAuto}); + // filament_config->set_key_value("filament_wipe_distance", new ConfigOptionFloats{0.0f}); + wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config(); wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); -} - -void Plater::calib_golden_ratio_flow(bool is_linear, int pass) { - wxString calib_name = L"GoldenRatio Flow Calibration Test 90-110%"; - if (new_project(false, false, calib_name) == wxID_CANCEL) - return; - - wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); - add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "golden-ratio-flow-test.3mf").string()); - adjust_settings_for_golden_ratio_flow_calib(model().objects, is_linear, pass); } // Adjust settings for flowrate calibration @@ -10007,7 +10028,6 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i _obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); _obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); - _obj->config.set_key_value("calib_test_mode", new ConfigOptionInt(CalibTestMode::CalibFlowrateTopInfillSpecialOrder)); // extract flowrate from name, filename format: flowrate_xxx std::string obj_name = _obj->name; @@ -10078,7 +10098,9 @@ void Plater::calib_flowrate(bool is_linear, int pass) { add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass2.3mf").string()); } - + Calib_Params params; + params.mode = CalibMode::Calib_Flow_Rate; + model().calib_params = params; adjust_settings_for_flowrate_calib(model().objects, is_linear, pass); wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 4d059e6b1b..25f879e581 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -277,6 +277,7 @@ public: 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); + void calib_golden_ratio_flow(const Calib_Params& params); BuildVolume_Type get_build_volume_type() const; diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index e36073ea45..154ba0dec0 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -1113,4 +1113,194 @@ void Junction_Deviation_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) { Fit(); } +// GoldenRatio_Flow_Test_Dlg +// + +GoldenRatio_Flow_Test_Dlg::GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater) + : DPIDialog(parent, id, _L("GoldenRatio flow calibration test"), wxDefaultPosition, parent->FromDIP(wxSize(-1, 280)), wxDEFAULT_DIALOG_STYLE) + , m_plater(plater) +{ + SetBackgroundColour(*wxWHITE); // make sure background color set for dialog + SetForegroundColour(wxColour("#363636")); + SetFont(Label::Body_14); + + wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL); + SetSizer(v_sizer); + + // Model selection + auto labeled_box_model = new LabeledStaticBox(this, _L("Model width")); + auto model_box = new wxStaticBoxSizer(labeled_box_model, wxHORIZONTAL); + m_rbModel = new RadioGroup(this, {"100 mm", "150 mm", "200 mm"}, wxHORIZONTAL); + for (auto &_el : m_rbModel->GetChildren()) // sets the note of range unit converting into flow ratio + _el->Bind(wxEVT_MOTION, &GoldenRatio_Flow_Test_Dlg::on_changed2, this); + model_box->Add(m_rbModel, 0, wxALL | wxEXPAND, FromDIP(4)); + v_sizer->Add(model_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); + + labeled_box_model = new LabeledStaticBox(this, _L("Model depth")); + model_box = new wxStaticBoxSizer(labeled_box_model, wxHORIZONTAL); + m_rbModelDepth = new RadioGroup(this, {"10 mm", "15 mm", "20 mm"}, wxHORIZONTAL); + model_box->Add(m_rbModelDepth, 0, wxALL | wxEXPAND, FromDIP(4)); + v_sizer->Add(model_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); + + // Settings + wxString start_fr_str = _L("Start flowrate value at:"); + wxString end_fr_str = _L("End flowrate value at:"); + wxString speed_fr_str = _L("Print speed (mm/s):"); + wxString interlaced_fr_str = _L("Interlaced:"); + wxString zhop_fr_str = _L("Use Z-Hop:"); + int text_max = GetTextMax(this, std::vector{start_fr_str, end_fr_str, speed_fr_str, interlaced_fr_str, zhop_fr_str}); + + auto st_size = FromDIP(wxSize(text_max, -1)); + auto ti_size = FromDIP(wxSize(120, -1)); + + LabeledStaticBox* stb = new LabeledStaticBox(this, _L("Print conditions")); + wxStaticBoxSizer* settings_sizer = new wxStaticBoxSizer(stb, wxVERTICAL); + + settings_sizer->AddSpacer(FromDIP(5)); + + // Start flow rate value + auto fr_sizer = new wxBoxSizer(wxHORIZONTAL); + auto start_fr_text = new wxStaticText(this, wxID_ANY, start_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiJDStart = new TextInput(this, wxString::Format("%.2f", 0.9), "", "", wxDefaultPosition, ti_size); + m_tiJDStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + m_tiJDStart->Bind(wxEVT_TEXT, &GoldenRatio_Flow_Test_Dlg::on_changed, this); + fr_sizer->Add(start_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + fr_sizer->Add(m_tiJDStart, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + + // End flow rate value + fr_sizer = new wxBoxSizer(wxHORIZONTAL); + auto end_fr_text = new wxStaticText(this, wxID_ANY, end_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiJDEnd = new TextInput(this, wxString::Format("%.2f", 1.1), "", "", wxDefaultPosition, ti_size); + m_tiJDEnd->Bind(wxEVT_TEXT, &GoldenRatio_Flow_Test_Dlg::on_changed, this); + m_tiJDEnd->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + fr_sizer->Add(end_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + fr_sizer->Add(m_tiJDEnd, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + settings_sizer->AddSpacer(FromDIP(5)); + + // Add note about junction deviation + m_stNote = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + m_stNote->SetForegroundColour(wxColour(128, 128, 128)); + settings_sizer->Add(m_stNote, 0, wxALL, FromDIP(5)); + settings_sizer->AddSpacer(FromDIP(5)); + + // Print speed value + fr_sizer = new wxBoxSizer(wxHORIZONTAL); + float _speed = 60; // plater->config()->get_abs_value("outer_wall_speed"); + auto speed_fr_text = new wxStaticText(this, wxID_ANY, speed_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiSpeed = new TextInput(this, wxString::Format("%.0f", _speed), "", "", wxDefaultPosition, ti_size); + m_tiSpeed->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + fr_sizer->Add(speed_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + fr_sizer->Add(m_tiSpeed, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + m_stNote->SetLabel(get_status()); + settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + settings_sizer->AddSpacer(FromDIP(5)); + + // Print settings + wxBoxSizer* cb_sizer = new wxBoxSizer(wxHORIZONTAL); + auto cb_title = new wxStaticText(this, wxID_ANY, interlaced_fr_str, wxDefaultPosition, st_size, 0); + m_cbInterlaced = new CheckBox(this); + m_cbInterlaced->SetValue(false); + cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + cb_sizer->Add(m_cbInterlaced, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + settings_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + settings_sizer->AddSpacer(FromDIP(5)); + cb_title = new wxStaticText(this, wxID_ANY, zhop_fr_str, wxDefaultPosition, st_size, 0); + m_cbUseZHop = new CheckBox(this); + m_cbUseZHop->SetValue(true); + cb_sizer = new wxBoxSizer(wxHORIZONTAL); + cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + cb_sizer->Add(m_cbUseZHop, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + settings_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + settings_sizer->AddSpacer(FromDIP(5)); + + v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); + v_sizer->AddSpacer(FromDIP(5)); + + auto dlg_btns = new DialogButtons(this, {"OK"}); + v_sizer->Add(dlg_btns, 0, wxEXPAND); + + dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &GoldenRatio_Flow_Test_Dlg::on_start, this); + + wxGetApp().UpdateDlgDarkUI(this); + + Layout(); + Fit(); +} + +GoldenRatio_Flow_Test_Dlg::~GoldenRatio_Flow_Test_Dlg() { + // Disconnect Events +} + +wxString GoldenRatio_Flow_Test_Dlg::get_status() { + 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 (m_params.end < m_params.start) + std::swap(m_params.end, m_params.start); + if (!read_double || m_params.start >= 0.5 && m_params.end <= 1.5) { + float const calib_scale[3] = {1.0f, 1.5f, 2.0f}; + float _phi = (m_params.end - m_params.start) * 10 / calib_scale[m_rbModel->GetSelection()]; + float _ksi; + for (_ksi = 1; _ksi < 6; _ksi++) { // Get a nice fractional value + float _teta = _phi * _ksi; + if (abs(_teta - round(_teta)) < 0.01) + break; + } + if (_ksi > 5) + _ksi = 1; + else + _phi *= _ksi; + return wxString::Format(_L("Current meas: %.0fcm = %.2f%% or %.4f"), _ksi, _phi, _phi * 0.01); + } else { + return _L("The value is out of range 0.5~1.5"); + } +} + +void GoldenRatio_Flow_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.5 || m_params.start > 1.5 || m_params.end < 0.5 || m_params.end > 1.5) { + MessageDialog msg_dlg(nullptr, _L("Please input valid values:\n(0.5 <= Flow Ratio <= 1.5)"), wxEmptyString, + wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } else if (m_params.end < m_params.start) { + std::swap(m_params.end, m_params.start); + MessageDialog msg_dlg(nullptr, _L("NOTE: Parameters has swapped!"), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + } + + m_params.mode = CalibMode::Calib_Golden_Ratio_Flow; + + // Set model type based on selection + m_params.test_model = m_rbModel->GetSelection(); + m_params.model_variant = m_rbModelDepth->GetSelection(); + m_params.interlaced = m_cbInterlaced->GetValue(); + m_params.use_zhop = m_cbUseZHop->GetValue(); + double _speed; + m_tiSpeed->GetTextCtrl()->GetValue().ToDouble(&_speed); + m_params.speeds.push_back(_speed); + m_plater->calib_golden_ratio_flow(m_params); + EndModal(wxID_OK); +} + +void GoldenRatio_Flow_Test_Dlg::on_changed(wxCommandEvent& event) { + m_stNote->SetLabel(get_status()); + event.Skip(); +} + +void GoldenRatio_Flow_Test_Dlg::on_changed2(wxMouseEvent& event) { + m_stNote->SetLabel(get_status()); + event.Skip(); +} + +void GoldenRatio_Flow_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) { + this->Refresh(); + Fit(); +} + }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/calib_dlg.hpp b/src/slic3r/GUI/calib_dlg.hpp index fd21c59ca9..0f7a9720c7 100644 --- a/src/slic3r/GUI/calib_dlg.hpp +++ b/src/slic3r/GUI/calib_dlg.hpp @@ -178,5 +178,30 @@ protected: TextInput* m_tiJDEnd; Plater* m_plater; }; + +class GoldenRatio_Flow_Test_Dlg : public DPIDialog +{ +public: + GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater); + ~GoldenRatio_Flow_Test_Dlg(); + void on_dpi_changed(const wxRect& suggested_rect) override; + wxString GoldenRatio_Flow_Test_Dlg::get_status(); + +protected: + virtual void on_start(wxCommandEvent& event); + virtual void on_changed(wxCommandEvent& event); + virtual void on_changed2(wxMouseEvent& event); + Calib_Params m_params; + + RadioGroup* m_rbModel; + RadioGroup* m_rbModelDepth; + TextInput* m_tiJDStart; + TextInput* m_tiJDEnd; + wxStaticText* m_stNote; + TextInput* m_tiSpeed; + CheckBox* m_cbInterlaced; + CheckBox* m_cbUseZHop; + Plater* m_plater; +}; }} // namespace Slic3r::GUI #endif From 8f5f943e6720263636b75fb6beb30d92049833a8 Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 28 Oct 2025 00:17:06 +0300 Subject: [PATCH 03/19] Update --- src/libslic3r/Fill/FillPlanePath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Fill/FillPlanePath.cpp b/src/libslic3r/Fill/FillPlanePath.cpp index 559efc5c9d..4b88a241ff 100644 --- a/src/libslic3r/Fill/FillPlanePath.cpp +++ b/src/libslic3r/Fill/FillPlanePath.cpp @@ -124,7 +124,7 @@ void FillPlanePath::_fill_surface_single( if (params.dont_connect() || params.density > 0.5) { // ORCA: special flag for flow rate calibration auto is_flow_calib = params.extrusion_role == erTopSolidInfill && - this->print_object_config->has("calib_test_mode") && + calib_params != nullptr && (calib_params->mode == CalibMode::Calib_Flow_Rate) && dynamic_cast(this); if (is_flow_calib) { From 599d033ed5cac7845f964acbd0e033ae1b2d3316 Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 28 Oct 2025 01:32:05 +0300 Subject: [PATCH 04/19] Update --- src/slic3r/GUI/MainFrame.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 05069c361e..8434f94bfc 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -364,7 +364,6 @@ public: 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 }; GoldenRatio_Flow_Test_Dlg* m_golden_ratio_flow_calib_dlg{ nullptr }; Cornering_Test_Dlg* m_cornering_calib_dlg{ nullptr }; From 2e7c716c222312760625170fdbfdbfb05cfb1c7a Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 28 Oct 2025 13:10:43 +0300 Subject: [PATCH 05/19] Update Plater.hpp --- src/slic3r/GUI/Plater.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index f58d0cb27f..68be9816a6 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -326,16 +326,14 @@ public: // SoftFever void calib_pa(const Calib_Params& params); - void calib_golden_ratio_flow(bool is_linear, int pass); void calib_flowrate(bool is_linear, int pass); + void calib_golden_ratio_flow(const Calib_Params& params); void calib_temp(const Calib_Params& params); 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); - void calib_golden_ratio_flow(const Calib_Params& params); void Calib_Cornering(const Calib_Params& params); BuildVolume_Type get_build_volume_type() const; From 7f8e7a2f1ce7321c5319644f56d10de23ec52dde Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Sat, 1 Nov 2025 00:24:54 +0300 Subject: [PATCH 06/19] Big Update: +Menu --- ...test.3mf => practical-flow-ratio-test.3mf} | Bin src/libslic3r/Fill/FillBase.cpp | 26 +++++-- src/libslic3r/calib.hpp | 2 +- src/slic3r/GUI/MainFrame.cpp | 11 +-- src/slic3r/GUI/MainFrame.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 32 ++++---- src/slic3r/GUI/Plater.hpp | 2 +- src/slic3r/GUI/calib_dlg.cpp | 69 +++++++++++------- src/slic3r/GUI/calib_dlg.hpp | 9 ++- 9 files changed, 89 insertions(+), 64 deletions(-) rename resources/calib/filament_flow/{golden-ratio-flow-test.3mf => practical-flow-ratio-test.3mf} (100%) diff --git a/resources/calib/filament_flow/golden-ratio-flow-test.3mf b/resources/calib/filament_flow/practical-flow-ratio-test.3mf similarity index 100% rename from resources/calib/filament_flow/golden-ratio-flow-test.3mf rename to resources/calib/filament_flow/practical-flow-ratio-test.3mf diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 97b1ebfe05..ab45db3eee 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -171,8 +171,9 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para eec->no_sort = true; break; } - case CalibMode::Calib_Golden_Ratio_Flow: + case CalibMode::Calib_Practical_Flow_Ratio: eec->no_sort = true; + //params.density = 0.5; } } @@ -198,9 +199,9 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para eec->entities[i]->set_reverse(); } break; - case CalibMode::Calib_Golden_Ratio_Flow: + case CalibMode::Calib_Practical_Flow_Ratio: eec->reverse(); - if (layer_id > 1) { + if (layer_id > 3) { double _wmin = this->calib_params->start; double _wmax = this->calib_params->end; double _wlen = _wmax - _wmin; @@ -235,12 +236,25 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para for (ExtrusionPath* _p : b) eec->entities.emplace_back(_p); } - } else if (layer_id == 1) + } else if (layer_id > 0) { // Prepare a smooth base + std::vector a; + int _i = 1; for (ExtrusionEntity* e : eec->entities) { ExtrusionPath* _p = static_cast(e); - _p->width *= 0.75; - _p->mm3_per_mm *= 0.75; + if (++_i % 2) { + if ((_i / 2) % 2) + _p->reverse(); + if (layer_id == 1) { + _p->width *= 0.75; + _p->mm3_per_mm *= 0.75; + } + a.emplace_back(_p); + } } + eec->entities.clear(); + for (ExtrusionPath* _p : a) + eec->entities.emplace_back(_p); + } } } else { // Orca: run gap fill diff --git a/src/libslic3r/calib.hpp b/src/libslic3r/calib.hpp index 2542c20e29..411838c42a 100644 --- a/src/libslic3r/calib.hpp +++ b/src/libslic3r/calib.hpp @@ -27,7 +27,7 @@ enum class CalibMode : int { Calib_Input_shaping_freq, Calib_Input_shaping_damp, Calib_Junction_Deviation, - Calib_Golden_Ratio_Flow, + Calib_Practical_Flow_Ratio, Calib_Cornering }; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 21519c1a05..0309017234 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -3043,13 +3043,10 @@ void MainFrame::init_menubar_as_editor() [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(true, 2); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); flowrate_menu->AppendSeparator(); - //append_menu_item(flowrate_menu, wxID_ANY, _L("GoldenRatio Flow Test"), _L("GoldenRatio Flow calibration test 90-110%"), - // [this](wxCommandEvent&) { if (m_plater) m_plater->calib_golden_ratio_flow(true, 1); }, "", nullptr, - // [this]() {return m_plater->is_view3D_shown();; }, this); - append_menu_item(flowrate_menu, wxID_ANY, _L("GoldenRatio Flow Test"), _L("GoldenRatio Flow calibration test 90-110%"), - [this](wxCommandEvent&) { if (!m_golden_ratio_flow_calib_dlg) - m_golden_ratio_flow_calib_dlg = new GoldenRatio_Flow_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater); - m_golden_ratio_flow_calib_dlg->ShowModal();}, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); + append_menu_item(flowrate_menu, wxID_ANY, _L("Practical Flow Ratio Test"), _L("Practical Flow Ratio calibration test"), + [this](wxCommandEvent&) { if (!m_practical_flow_ratio_calib_dlg) + m_practical_flow_ratio_calib_dlg = new Practical_Flow_Ratio_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater); + m_practical_flow_ratio_calib_dlg->ShowModal();}, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); m_topbar->GetCalibMenu()->AppendSubMenu(flowrate_menu, _L("Flow rate")); // Pressure Advance diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 8434f94bfc..ef5c7a4a0a 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -364,7 +364,7 @@ public: 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 }; - GoldenRatio_Flow_Test_Dlg* m_golden_ratio_flow_calib_dlg{ nullptr }; + Practical_Flow_Ratio_Test_Dlg* m_practical_flow_ratio_calib_dlg{ nullptr }; Cornering_Test_Dlg* m_cornering_calib_dlg{ nullptr }; // BBS. Replace title bar and menu bar with top bar. diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 65f5a3d75d..b17f9d4064 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -11940,13 +11940,13 @@ void Plater::_calib_pa_select_added_objects() { } } -// Adjust settings for golden ratio flow calibration -void Plater::calib_golden_ratio_flow(const Calib_Params& params) { - wxString calib_name = L"GoldenRatio Flow Test"; +// Adjust settings for Practical Flow ratio calibration +void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { + wxString calib_name = L"Practical Flow Ratio Test"; if (new_project(false, false, calib_name) == wxID_CANCEL) return; wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); - add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "golden-ratio-flow-test.3mf").string()); + add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "practical-flow-ratio-test.3mf").string()); auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; @@ -11968,9 +11968,9 @@ void Plater::calib_golden_ratio_flow(const Calib_Params& params) { TransformationType transformation_type; transformation_type.set_relative(); float const calib_scale[3] = {1.0f, 1.5f, 2.0f}; - float zscale = (first_layer_height + 5 * layer_height) / 1.2; - float xscale = calib_scale[params.test_model]; - float yscale = calib_scale[params.model_variant]; + float zscale = (first_layer_height + (3 + params.step) * layer_height) / 1.2; + float xscale = calib_scale[params.test_model]; + float yscale = calib_scale[params.model_variant]; // only enlarge selection.scale({xscale, yscale, zscale}, transformation_type); @@ -11994,11 +11994,11 @@ void Plater::calib_golden_ratio_flow(const Calib_Params& params) { _obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(2)); _obj->config.set_key_value("bottom_surface_pattern", new ConfigOptionEnum(ipMonotonic)); _obj->config.set_key_value("bottom_shell_thickness", new ConfigOptionFloat(0)); - _obj->config.set_key_value("bottom_surface_density", new ConfigOptionPercent(90)); + _obj->config.set_key_value("bottom_surface_density", new ConfigOptionPercent(100)); _obj->config.set_key_value("sparse_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); _obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(100)); _obj->config.set_key_value("solid_infill_direction", new ConfigOptionFloat(0)); - _obj->config.set_key_value("solid_infill_rotate_template", new ConfigOptionString("90, 0, 90#100")); + _obj->config.set_key_value("solid_infill_rotate_template", new ConfigOptionString("45, 0, 90, 0, 90#100")); _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("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); @@ -12009,7 +12009,7 @@ void Plater::calib_golden_ratio_flow(const Calib_Params& params) { _obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed _obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); _obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); - _obj->name = format("GoldenRatio_Flow_Test_%.2f~%.2f_@%fmmps", params.start, params.end, params.speeds[0]); + _obj->name = format("Practical_FR_Test_%.2f~%.2f_%s@%fmmps", params.start, params.end, params.interlaced ? "i" : "p", params.speeds[0]); } print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); @@ -12019,14 +12019,14 @@ void Plater::calib_golden_ratio_flow(const Calib_Params& params) { print_config->set_key_value("reduce_crossing_wall", new ConfigOptionBool(true)); printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{RetractLiftEnforceType::rletAllSurfaces}); - printer_config->set_key_value("z_hop", new ConfigOptionFloats{params.use_zhop ? 1.0f : 0.0f}); - printer_config->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtNormal}); + printer_config->set_key_value("z_hop", new ConfigOptionFloats{params.use_zhop ? 0.4f : 0.0f}); + printer_config->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtSlope}); printer_config->set_key_value("wipe_distance", new ConfigOptionFloats{0.0f}); - // filament_config->set_key_value("filament_retract_lift_enforce", new ConfigOptionEnumsGeneric{RetractLiftEnforceType::rletAllSurfaces}); - // filament_config->set_key_value("filament_z_hop", new ConfigOptionFloats{0.0f}); - // filament_config->set_key_value("filament_z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtAuto}); - // filament_config->set_key_value("filament_wipe_distance", new ConfigOptionFloats{0.0f}); + filament_config->set_key_value("filament_z_hop", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + filament_config->set_key_value("filament_wipe_distance", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + filament_config->set_key_value("filament_retract_lift_enforce", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); + filament_config->set_key_value("filament_z_hop_types", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 68be9816a6..cc87069de1 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -327,7 +327,7 @@ public: // SoftFever void calib_pa(const Calib_Params& params); void calib_flowrate(bool is_linear, int pass); - void calib_golden_ratio_flow(const Calib_Params& params); + void Calib_Practical_Flow_Ratio(const Calib_Params& params); void calib_temp(const Calib_Params& params); void calib_max_vol_speed(const Calib_Params& params); void calib_retraction(const Calib_Params& params); diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index 5d98f29175..7cd73800ad 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -1411,11 +1411,10 @@ void Cornering_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) { Fit(); } -// GoldenRatio_Flow_Test_Dlg -// +// Practical_Flow_Ratio_Test_Dlg -GoldenRatio_Flow_Test_Dlg::GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater) - : DPIDialog(parent, id, _L("GoldenRatio flow calibration test"), wxDefaultPosition, parent->FromDIP(wxSize(-1, 280)), wxDEFAULT_DIALOG_STYLE) +Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater) + : DPIDialog(parent, id, _L("Prectical flow ratio calibration test"), wxDefaultPosition, parent->FromDIP(wxSize(-1, 280)), wxDEFAULT_DIALOG_STYLE) , m_plater(plater) { SetBackgroundColour(*wxWHITE); // make sure background color set for dialog @@ -1425,12 +1424,21 @@ GoldenRatio_Flow_Test_Dlg::GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowI wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL); SetSizer(v_sizer); + // Settings + wxString start_fr_str = _L("Start flowrate value at:"); + wxString end_fr_str = _L("End flowrate value at:"); + wxString quant_fr_str = _L("Number of calibration layers (4~40):"); + wxString speed_fr_str = _L("Print speed:"); + wxString interlaced_fr_str = _L("Interlaced:"); + wxString zhop_fr_str = _L("Use Z-Hop:"); + int text_max = GetTextMax(this, std::vector{start_fr_str, end_fr_str, quant_fr_str, speed_fr_str, interlaced_fr_str, zhop_fr_str}); + // Model selection auto labeled_box_model = new LabeledStaticBox(this, _L("Model width")); auto model_box = new wxStaticBoxSizer(labeled_box_model, wxHORIZONTAL); m_rbModel = new RadioGroup(this, {"100 mm", "150 mm", "200 mm"}, wxHORIZONTAL); for (auto &_el : m_rbModel->GetChildren()) // sets the note of range unit converting into flow ratio - _el->Bind(wxEVT_MOTION, &GoldenRatio_Flow_Test_Dlg::on_changed2, this); + _el->Bind(wxEVT_MOTION, &Practical_Flow_Ratio_Test_Dlg::on_changed2, this); model_box->Add(m_rbModel, 0, wxALL | wxEXPAND, FromDIP(4)); v_sizer->Add(model_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); @@ -1440,14 +1448,6 @@ GoldenRatio_Flow_Test_Dlg::GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowI model_box->Add(m_rbModelDepth, 0, wxALL | wxEXPAND, FromDIP(4)); v_sizer->Add(model_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); - // Settings - wxString start_fr_str = _L("Start flowrate value at:"); - wxString end_fr_str = _L("End flowrate value at:"); - wxString speed_fr_str = _L("Print speed (mm/s):"); - wxString interlaced_fr_str = _L("Interlaced:"); - wxString zhop_fr_str = _L("Use Z-Hop:"); - int text_max = GetTextMax(this, std::vector{start_fr_str, end_fr_str, speed_fr_str, interlaced_fr_str, zhop_fr_str}); - auto st_size = FromDIP(wxSize(text_max, -1)); auto ti_size = FromDIP(wxSize(120, -1)); @@ -1461,7 +1461,7 @@ GoldenRatio_Flow_Test_Dlg::GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowI auto start_fr_text = new wxStaticText(this, wxID_ANY, start_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); m_tiJDStart = new TextInput(this, wxString::Format("%.2f", 0.9), "", "", wxDefaultPosition, ti_size); m_tiJDStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); - m_tiJDStart->Bind(wxEVT_TEXT, &GoldenRatio_Flow_Test_Dlg::on_changed, this); + m_tiJDStart->Bind(wxEVT_TEXT, &Practical_Flow_Ratio_Test_Dlg::on_changed, this); fr_sizer->Add(start_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); fr_sizer->Add(m_tiJDStart, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); @@ -1470,7 +1470,7 @@ GoldenRatio_Flow_Test_Dlg::GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowI fr_sizer = new wxBoxSizer(wxHORIZONTAL); auto end_fr_text = new wxStaticText(this, wxID_ANY, end_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); m_tiJDEnd = new TextInput(this, wxString::Format("%.2f", 1.1), "", "", wxDefaultPosition, ti_size); - m_tiJDEnd->Bind(wxEVT_TEXT, &GoldenRatio_Flow_Test_Dlg::on_changed, this); + m_tiJDEnd->Bind(wxEVT_TEXT, &Practical_Flow_Ratio_Test_Dlg::on_changed, this); m_tiJDEnd->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); fr_sizer->Add(end_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); fr_sizer->Add(m_tiJDEnd, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -1480,18 +1480,28 @@ GoldenRatio_Flow_Test_Dlg::GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowI // Add note about junction deviation m_stNote = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_stNote->SetForegroundColour(wxColour(128, 128, 128)); + m_stNote->SetLabel(get_status()); settings_sizer->Add(m_stNote, 0, wxALL, FromDIP(5)); settings_sizer->AddSpacer(FromDIP(5)); - // Print speed value + // Print speed value m_tiQuantity + fr_sizer = new wxBoxSizer(wxHORIZONTAL); + auto quant_fr_text = new wxStaticText(this, wxID_ANY, quant_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiQuantity = new TextInput(this, wxString::Format("%.0f", 10.0f), "", "", wxDefaultPosition, ti_size); + m_tiQuantity->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + fr_sizer->Add(quant_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + fr_sizer->Add(m_tiQuantity, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + settings_sizer->AddSpacer(FromDIP(5)); + fr_sizer = new wxBoxSizer(wxHORIZONTAL); float _speed = 60; // plater->config()->get_abs_value("outer_wall_speed"); auto speed_fr_text = new wxStaticText(this, wxID_ANY, speed_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); m_tiSpeed = new TextInput(this, wxString::Format("%.0f", _speed), "", "", wxDefaultPosition, ti_size); m_tiSpeed->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + m_tiSpeed->SetLabel("mm/s"); fr_sizer->Add(speed_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); fr_sizer->Add(m_tiSpeed, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); - m_stNote->SetLabel(get_status()); settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); settings_sizer->AddSpacer(FromDIP(5)); @@ -1519,7 +1529,7 @@ GoldenRatio_Flow_Test_Dlg::GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowI auto dlg_btns = new DialogButtons(this, {"OK"}); v_sizer->Add(dlg_btns, 0, wxEXPAND); - dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &GoldenRatio_Flow_Test_Dlg::on_start, this); + dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &Practical_Flow_Ratio_Test_Dlg::on_start, this); wxGetApp().UpdateDlgDarkUI(this); @@ -1527,11 +1537,11 @@ GoldenRatio_Flow_Test_Dlg::GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowI Fit(); } -GoldenRatio_Flow_Test_Dlg::~GoldenRatio_Flow_Test_Dlg() { +Practical_Flow_Ratio_Test_Dlg::~Practical_Flow_Ratio_Test_Dlg() { // Disconnect Events } -wxString GoldenRatio_Flow_Test_Dlg::get_status() { +wxString Practical_Flow_Ratio_Test_Dlg::get_status() { 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); @@ -1556,14 +1566,17 @@ wxString GoldenRatio_Flow_Test_Dlg::get_status() { } } -void GoldenRatio_Flow_Test_Dlg::on_start(wxCommandEvent& event) { +void Practical_Flow_Ratio_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.5 || m_params.start > 1.5 || m_params.end < 0.5 || m_params.end > 1.5) { - MessageDialog msg_dlg(nullptr, _L("Please input valid values:\n(0.5 <= Flow Ratio <= 1.5)"), wxEmptyString, - wxICON_WARNING | wxOK); + MessageDialog msg_dlg(nullptr, _L("Please input valid values:\n(0.5 <= Flow Ratio <= 1.5)"), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } else if (!m_tiQuantity->GetTextCtrl()->GetValue().ToDouble(&m_params.step) || m_params.step < 4 || m_params.step > 20) { + MessageDialog msg_dlg(nullptr, _L("Please input valid layer value:\n(4 <= Number of Calibration Layers <= 40)"), wxEmptyString, wxICON_WARNING | wxOK); msg_dlg.ShowModal(); return; } else if (m_params.end < m_params.start) { @@ -1572,7 +1585,7 @@ void GoldenRatio_Flow_Test_Dlg::on_start(wxCommandEvent& event) { msg_dlg.ShowModal(); } - m_params.mode = CalibMode::Calib_Golden_Ratio_Flow; + m_params.mode = CalibMode::Calib_Practical_Flow_Ratio; // Set model type based on selection m_params.test_model = m_rbModel->GetSelection(); @@ -1582,21 +1595,21 @@ void GoldenRatio_Flow_Test_Dlg::on_start(wxCommandEvent& event) { double _speed; m_tiSpeed->GetTextCtrl()->GetValue().ToDouble(&_speed); m_params.speeds.push_back(_speed); - m_plater->calib_golden_ratio_flow(m_params); + m_plater->Calib_Practical_Flow_Ratio(m_params); EndModal(wxID_OK); } -void GoldenRatio_Flow_Test_Dlg::on_changed(wxCommandEvent& event) { +void Practical_Flow_Ratio_Test_Dlg::on_changed(wxCommandEvent& event) { m_stNote->SetLabel(get_status()); event.Skip(); } -void GoldenRatio_Flow_Test_Dlg::on_changed2(wxMouseEvent& event) { +void Practical_Flow_Ratio_Test_Dlg::on_changed2(wxMouseEvent& event) { m_stNote->SetLabel(get_status()); event.Skip(); } -void GoldenRatio_Flow_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) { +void Practical_Flow_Ratio_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) { this->Refresh(); Fit(); } diff --git a/src/slic3r/GUI/calib_dlg.hpp b/src/slic3r/GUI/calib_dlg.hpp index b02f968ea9..d315452ace 100644 --- a/src/slic3r/GUI/calib_dlg.hpp +++ b/src/slic3r/GUI/calib_dlg.hpp @@ -181,13 +181,13 @@ protected: Plater* m_plater; }; -class GoldenRatio_Flow_Test_Dlg : public DPIDialog +class Practical_Flow_Ratio_Test_Dlg : public DPIDialog { public: - GoldenRatio_Flow_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater); - ~GoldenRatio_Flow_Test_Dlg(); + Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater); + ~Practical_Flow_Ratio_Test_Dlg(); void on_dpi_changed(const wxRect& suggested_rect) override; - wxString GoldenRatio_Flow_Test_Dlg::get_status(); + wxString Practical_Flow_Ratio_Test_Dlg::get_status(); protected: virtual void on_start(wxCommandEvent& event); @@ -201,6 +201,7 @@ protected: TextInput* m_tiJDEnd; wxStaticText* m_stNote; TextInput* m_tiSpeed; + TextInput* m_tiQuantity; CheckBox* m_cbInterlaced; CheckBox* m_cbUseZHop; Plater* m_plater; From 86980e3e4275b2ad0dc4fbb50584fb8901cdedbd Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Sat, 1 Nov 2025 03:39:01 +0300 Subject: [PATCH 07/19] Update calib_dlg.cpp --- src/slic3r/GUI/calib_dlg.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index 7cd73800ad..e557e37c05 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -1594,6 +1594,7 @@ void Practical_Flow_Ratio_Test_Dlg::on_start(wxCommandEvent& event) { m_params.use_zhop = m_cbUseZHop->GetValue(); double _speed; m_tiSpeed->GetTextCtrl()->GetValue().ToDouble(&_speed); + m_params.speeds.clear(); m_params.speeds.push_back(_speed); m_plater->Calib_Practical_Flow_Ratio(m_params); EndModal(wxID_OK); From f622b7fbb9f6a74d47f2947cc7214bfc39655e6e Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Wed, 5 Nov 2025 23:58:58 +0300 Subject: [PATCH 08/19] Update config --- src/slic3r/GUI/Plater.cpp | 73 ++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b17f9d4064..ba279de7ee 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -11978,37 +11978,48 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { model().calib_params = params; // adjust parameters + print_config->set_key_value("wall_loops", new ConfigOptionInt(1)); + print_config->set_key_value("internal_bridge_density", new ConfigOptionPercent(100)); + print_config->set_key_value("thick_internal_bridges", new ConfigOptionBool(false)); + print_config->set_key_value("enable_extra_bridge_layer", new ConfigOptionEnum(eblDisabled)); + print_config->set_key_value("min_width_top_surface", new ConfigOptionFloatOrPercent(100, true)); + print_config->set_key_value("only_one_wall_top", new ConfigOptionBool(true)); + print_config->set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f)); + print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0)); + print_config->set_key_value("top_surface_pattern", new ConfigOptionEnum(ipMonotonicLine)); + print_config->set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f)); + print_config->set_key_value("top_shell_thickness", new ConfigOptionFloat(0)); + print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(2)); + print_config->set_key_value("bottom_surface_pattern", new ConfigOptionEnum(ipMonotonic)); + print_config->set_key_value("bottom_shell_thickness", new ConfigOptionFloat(0)); + print_config->set_key_value("bottom_surface_density", new ConfigOptionPercent(100)); + print_config->set_key_value("sparse_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); + print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(100)); + print_config->set_key_value("solid_infill_direction", new ConfigOptionFloat(0)); + print_config->set_key_value("solid_infill_rotate_template", new ConfigOptionString("45, 0, 90, 0, 90#100")); + print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(true)); + print_config->set_key_value("filter_out_gap_fill", new ConfigOptionFloat(0)); + print_config->set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); + print_config->set_key_value("infill_direction", new ConfigOptionFloat(0)); + print_config->set_key_value("internal_solid_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); + print_config->set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true)); + print_config->set_key_value("ironing_type", new ConfigOptionEnum(IroningType::NoIroning)); + print_config->set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed + print_config->set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); + print_config->set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); + print_config->set_key_value("fuzzy_skin", new ConfigOptionEnum(FuzzySkinType::None)); + + print_config->set_key_value("line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); + print_config->set_key_value("initial_layer_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("outer_wall_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("inner_wall_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("top_surface_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("sparse_infill_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("support_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + for (auto _obj : model().objects) { _obj->ensure_on_bed(); - _obj->config.set_key_value("wall_loops", new ConfigOptionInt(1)); - _obj->config.set_key_value("internal_bridge_density", new ConfigOptionPercent(100)); - _obj->config.set_key_value("thick_internal_bridges", new ConfigOptionBool(false)); - _obj->config.set_key_value("enable_extra_bridge_layer", new ConfigOptionEnum(eblDisabled)); - _obj->config.set_key_value("min_width_top_surface", new ConfigOptionFloatOrPercent(100, true)); - _obj->config.set_key_value("only_one_wall_top", new ConfigOptionBool(true)); - _obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f)); - _obj->config.set_key_value("top_shell_layers", new ConfigOptionInt(0)); - _obj->config.set_key_value("top_surface_pattern", new ConfigOptionEnum(ipMonotonicLine)); - _obj->config.set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f)); - _obj->config.set_key_value("top_shell_thickness", new ConfigOptionFloat(0)); - _obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(2)); - _obj->config.set_key_value("bottom_surface_pattern", new ConfigOptionEnum(ipMonotonic)); - _obj->config.set_key_value("bottom_shell_thickness", new ConfigOptionFloat(0)); - _obj->config.set_key_value("bottom_surface_density", new ConfigOptionPercent(100)); - _obj->config.set_key_value("sparse_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); - _obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(100)); - _obj->config.set_key_value("solid_infill_direction", new ConfigOptionFloat(0)); - _obj->config.set_key_value("solid_infill_rotate_template", new ConfigOptionString("45, 0, 90, 0, 90#100")); - _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("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); - _obj->config.set_key_value("infill_direction", new ConfigOptionFloat(0)); - _obj->config.set_key_value("internal_solid_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); - _obj->config.set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true)); - _obj->config.set_key_value("ironing_type", new ConfigOptionEnum(IroningType::NoIroning)); - _obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed - _obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); - _obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); _obj->name = format("Practical_FR_Test_%.2f~%.2f_%s@%fmmps", params.start, params.end, params.interlaced ? "i" : "p", params.speeds[0]); } @@ -12028,12 +12039,12 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { filament_config->set_key_value("filament_retract_lift_enforce", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); filament_config->set_key_value("filament_z_hop_types", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); - wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty(); - wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config(); + wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config(); wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); + wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config(); } // Adjust settings for flowrate calibration From 992eacf25632451f3c0e41741e950ee5fcc7adba Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Wed, 19 Nov 2025 18:38:01 +0300 Subject: [PATCH 09/19] pre-finish --- .../practical-flow-ratio-test.3mf | Bin 24159 -> 0 bytes src/libslic3r/Emboss.cpp | 10 + src/libslic3r/Emboss.hpp | 10 + src/libslic3r/Fill/FillBase.cpp | 25 +- src/libslic3r/calib.hpp | 4 +- src/slic3r/GUI/Plater.cpp | 254 ++++++++++++++++-- src/slic3r/GUI/calib_dlg.cpp | 106 +++++--- src/slic3r/GUI/calib_dlg.hpp | 3 + 8 files changed, 342 insertions(+), 70 deletions(-) delete mode 100644 resources/calib/filament_flow/practical-flow-ratio-test.3mf diff --git a/resources/calib/filament_flow/practical-flow-ratio-test.3mf b/resources/calib/filament_flow/practical-flow-ratio-test.3mf deleted file mode 100644 index 25f72b994fdbd3806866b6005d713fda7227aa8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24159 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 diff --git a/src/libslic3r/Emboss.cpp b/src/libslic3r/Emboss.cpp index ef144b48d3..af9f6404ec 100644 --- a/src/libslic3r/Emboss.cpp +++ b/src/libslic3r/Emboss.cpp @@ -1299,6 +1299,16 @@ HealedExPolygons Emboss::text2shapes(FontFileWithCache &font_with_cache, const c return ::union_with_delta(vshapes, delta, MAX_HEAL_ITERATION_OF_TEXT); } +indexed_triangle_set Emboss::text2model(FontFileWithCache &font, const char *text, const FontProp &font_prop, Vec3d &dx_y_z_size) +{ + const double scale = 0.000001 * 25.4 / 72 * dx_y_z_size.y(); // convert points to millimeters (represent interliniage) + const double width = dx_y_z_size.x() ? dx_y_z_size.x() : 1.0; + const auto shapes = Emboss::text2shapes(font, text, font_prop, []() { return false; }); + auto pt = std::make_unique(dx_y_z_size.z()); + Transform3d tr = Eigen::Translation() * Eigen::Scaling(scale * width, scale, 1.); + return Emboss::polygons2model(shapes.expolygons, Emboss::ProjectTransform(std::move(pt), tr)); +} + namespace { /// /// Align shape against pivot diff --git a/src/libslic3r/Emboss.hpp b/src/libslic3r/Emboss.hpp index 15f0316327..2791cbfb20 100644 --- a/src/libslic3r/Emboss.hpp +++ b/src/libslic3r/Emboss.hpp @@ -155,6 +155,16 @@ namespace Emboss HealedExPolygons text2shapes (FontFileWithCache &font, const char *text, const FontProp &font_prop, const std::function &was_canceled = []() {return false;}); ExPolygonsWithIds text2vshapes(FontFileWithCache &font, const std::wstring& text, const FontProp &font_prop, const std::function& was_canceled = []() {return false;}); + /// + /// Convert text into triangle set + /// + /// Define fonts + cache, which could extend + /// Characters to convert + /// User defined property of the font + /// The size of the printed text {dx, y, z}. "dx" is the width of the character relative to its size (default is 1.0). "y" is the font height in millimeters. "z"S is the height of the extruded text in millimeters. + /// Indexed triangle set + indexed_triangle_set text2model(FontFileWithCache& font, const char *text, const FontProp &font_prop, Vec3d &dx_y_z_size); + const unsigned ENTER_UNICODE = static_cast('\n'); /// Sum of character '\n' unsigned get_count_lines(const std::wstring &ws); diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index ab45db3eee..51ae8a35fe 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -172,7 +172,8 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para break; } case CalibMode::Calib_Practical_Flow_Ratio: - eec->no_sort = true; + if (layer_id > 3) + eec->no_sort = true; //params.density = 0.5; } } @@ -200,17 +201,16 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para } break; case CalibMode::Calib_Practical_Flow_Ratio: - eec->reverse(); - if (layer_id > 3) { - double _wmin = this->calib_params->start; - double _wmax = this->calib_params->end; - double _wlen = _wmax - _wmin; - BoundingBox _bbox = this->bounding_box; - coord_t _width = _bbox.size().x(); - coord_t _semiwidth = _width / 2; - coord_t _xmin = _bbox.center().x() - _semiwidth; - coord_t _xmax = _bbox.center().x() + _semiwidth; - + const BoundingBox _bbox = this->bounding_box; + const coord_t _width = _bbox.size().x(); + const coord_t _semiwidth = _width / 2; + const coord_t _xmin = _bbox.center().x() - _semiwidth; + const coord_t _xmax = _bbox.center().x() + _semiwidth; + const double _wmin = this->calib_params->start; + const double _wmax = this->calib_params->end; + const double _wlen = _wmax - _wmin; + if (layer_id > 3) { // Prepare calibration layers + eec->reverse(); for (ExtrusionEntity* e : eec->entities) { ExtrusionPath* _p = static_cast(e); coord_t _x = _p->polyline.points.front().x(); @@ -254,6 +254,7 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para eec->entities.clear(); for (ExtrusionPath* _p : a) eec->entities.emplace_back(_p); + } else { // Additional job at first layer } } } else { diff --git a/src/libslic3r/calib.hpp b/src/libslic3r/calib.hpp index 411838c42a..0353a87887 100644 --- a/src/libslic3r/calib.hpp +++ b/src/libslic3r/calib.hpp @@ -37,8 +37,8 @@ struct Calib_Params { Calib_Params() : mode(CalibMode::Calib_None){}; int extruder_id = 0; - double start, end, step; - bool print_numbers, use_zhop, interlaced; + double start, end, step; + bool print_numbers, print_ruler, use_zhop, interlaced; double freqStartX, freqEndX, freqStartY, freqEndY; int test_model, model_variant; std::string shaper_type; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ba279de7ee..c617c213e0 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef _WIN32 #include #include @@ -164,6 +165,9 @@ #include "DeviceCore/DevFilaSystem.h" #include "DeviceCore/DevManager.h" +#include "../Utils/WxFontUtils.hpp" +#include "libslic3r/TextConfiguration.hpp" + using boost::optional; namespace fs = boost::filesystem; using Slic3r::_3DScene; @@ -216,6 +220,79 @@ wxDEFINE_EVENT(EVT_NOTICE_FULL_SCREEN_CHANGED, IntEvent); #define PRINTER_PANEL_SIZE (wxSize(FromDIP(96), FromDIP(98))) #define BTN_SYNC_SIZE (wxSize(FromDIP(96), FromDIP(98))) +wxFont calib_font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, "NotoSans"); +Emboss::FontFileWithCache calib_font_with_cache(std::move(WxFontUtils::create_font_file(calib_font))); + +/// +/// Get the orthogonal box mesh (Experemental, can rethink and add) +/// +/// The size of the printed text {dx, y, z}. +/// "dx" is the width of the character relative to its size (default is 1.0). +/// "y" is the font height in millimeters. +/// "z" is the height of the extruded text in millimeters. +/// Position of model against text pivot. +static TriangleMesh get_ortho_box_mesh(Vec3d& size, Vec3f& position = Vec3f()) +{ + TriangleMesh mesh(make_cube(size.x(), size.y(), size.z())); // get box + mesh.translate(position); // move mesh to indeed place + return mesh; +} + +/// +/// Get the triangle mesh (Experemental, can rethink and add) +/// +/// The size of the printed text {x, y, z}. +/// "x" is the size of the triangle in millimeters. +/// "y" define the line width in millimeters. +/// "z" is the height of the extruded shape in millimeters. +/// Position of model against its pivot. +/// Rotation angle of model against its pivot. +static TriangleMesh get_ortho_triangle_mesh(Vec3d &size, Vec3f &position = Vec3f(), double rotation = 0.) +{ + TriangleMesh mesh(make_cube(size.y(), size.x(), size.z())); // get triangle side + double _ypos = size.x() * sin(PI / 3); + mesh.translate(-size.y() / 2, 0., 0.); + TriangleMesh mesh2(mesh); + mesh2.rotate_z(PI / 3); + TriangleMesh mesh3(mesh2); + mesh3.rotate_z(PI / 3); + mesh.translate(-_ypos, -size.x() / 2, 0.); + mesh.merge(std::move(mesh2)); + mesh.merge(std::move(mesh3)); + mesh.rotate_z(rotation * PI / 180); + mesh.translate(position); // move mesh to indeed place + return mesh; +} + + +/// +/// Get the text mesh (Experemental, can rethink and add) +/// +/// The text +/// Font properties. Containe Horizontal and vertical alignment. +/// The size of the printed text {dx, y, z}. +/// "dx" is the width of the character relative to its size (default is 1.0). +/// "y" is the font height in millimeters. +/// "z" is the height of the extruded text in millimeters. +/// Position of model against text pivot +/// Place background box under text {depth, offset} +/// "depth" is the depth of the background box. Its height is added to the height of the entire model. +/// "offset" external expansion relative to the borders of the text. +static TriangleMesh get_text_mesh(const char *text, FontProp &font_props, Vec3d &size, Vec3f &position = Vec3f(), Vec2f &background = Vec2f()) +{ + TriangleMesh mesh( + Emboss::text2model(calib_font_with_cache, text, font_props, Vec3d(size.x(), size.y(), size.z() + background.x()))); // get text mesh + if (background.x()) { + BoundingBoxf3 bb3 = mesh.bounding_box(); + float offset = background.y(); + TriangleMesh mesh_bg = get_ortho_box_mesh(Vec3d(bb3.size().x() + offset * 2, bb3.size().y() + offset * 2, background.x()), + Vec3f(bb3.min.x() - offset, bb3.min.y() - offset, 0.)); + mesh.merge(mesh_bg); + } + mesh.translate(position); // move text mesh to indeed place + return mesh; +} + static string get_diameter_string(float diameter) { std::ostringstream stream; @@ -11946,7 +12023,6 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { if (new_project(false, false, calib_name) == wxID_CANCEL) return; wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); - add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "practical-flow-ratio-test.3mf").string()); auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; @@ -11956,27 +12032,161 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { // model is created for a 0.4 nozzle, scale z with nozzle size. const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter"); assert(nozzle_diameter_config->values.size() > 0); - float nozzle_diameter = nozzle_diameter_config->values[0]; + const double nozzle_diameter = nozzle_diameter_config->values[0]; // scale z to have 6 layers - 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); + double first_layer_height = print_config->option("initial_layer_print_height")->value; + const 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); - const auto canvas = wxGetApp().plater()->canvas3D(); - auto& selection = canvas->get_selection(); - selection.setup_cache(); - TransformationType transformation_type; - transformation_type.set_relative(); - float const calib_scale[3] = {1.0f, 1.5f, 2.0f}; - float zscale = (first_layer_height + (3 + params.step) * layer_height) / 1.2; - float xscale = calib_scale[params.test_model]; - float yscale = calib_scale[params.model_variant]; + const double calib_scale[3] = {1.0, 1.5, 2.0}; + const double xscale = calib_scale[params.test_model]; + const double yscale = calib_scale[params.model_variant]; + const double zscale = (first_layer_height + (3 + params.step) * layer_height) / 1.2; - // only enlarge - selection.scale({xscale, yscale, zscale}, transformation_type); - canvas->do_scale(""); model().calib_params = params; + string _name = format("Practical_FR_Test_%.2f~%.2f_@%.0f%s", params.start, params.end, params.speeds[0], params.interlaced ? "i" : "p"); + + const auto bed_shape = printer_config->option("printable_area")->values; + const BoundingBoxf bed_ext = get_extents(bed_shape); + const Vec2d _center = bed_ext.center(); + + auto test_model = model().add_object(); + TriangleMesh its_model = TriangleMesh(make_cube(xscale * 100, yscale * 10, zscale * 1.2)); + test_model->name = _name; + test_model->add_volume(its_model); + test_model->add_instance(); + + test_model->translate_instances(Vec3d(_center.x() - xscale * 50, _center.y() - yscale * 5, 0.0)); + test_model->ensure_on_bed(); + + const BoundingBoxf3 _bbox = test_model->bounding_box_exact(); + const double _width = _bbox.size().x(); // model width + const double _depth = _bbox.size().y(); // model depth + const double _div_width = nozzle_diameter * 1.25; // divider width for rulers + const double _div_semiwidth = _div_width / 2.; // divider half of width for rulers + const double _body_height = first_layer_height + layer_height; // rulers height + const double _offset = nozzle_diameter * 2.; // text labels offset + const double _font_size = nozzle_diameter * 16.25; // font size + Vec3d _size(1., _font_size, layer_height * 2.); // text dimensions + FontProp fp; // text properties + Vec2f _bg(_body_height, _offset); // set text background plate + const auto _filament_fr = filament_config->option("filament_flow_ratio")->get_at(0); // filament flow ratio + const auto _real_fr = 1. / _filament_fr; // filament flow ratio mark position + + if (params.print_ruler) { // Print ruler + const double _baseline = nozzle_diameter * 5; // baseline offset + test_model->add_volume(get_ortho_box_mesh(Vec3d(_width + _div_width, -_baseline + nozzle_diameter, _body_height), + Vec3f(-_div_semiwidth, -nozzle_diameter, 0.))); // ruler's body + + fp.align = FontProp::Align(FontProp::HorizontalAlign::right, FontProp::VerticalAlign::bottom); // correct the text position + TriangleMesh mesh = get_text_mesh(format("%s@%.0f%s fr=%.3f", filament_config->get_filament_type(), params.speeds[0], params.interlaced ? "i" : "p", _filament_fr).c_str(), fp, _size, + Vec3f(_width - _offset + _div_semiwidth, 0., 0.), _bg); + const double _basedepth = mesh.bounding_box().size().y() + 7.; // ruler's base depth + const double _delta_y = _baseline + _basedepth; // y displacement + mesh.translate(Vec3f(0., -_delta_y + _offset + _div_semiwidth, 0.)); + test_model->add_volume(mesh); + + double _phi = (params.end - params.start) * 10 / calib_scale[params.test_model]; + double _ksi; + for (_ksi = 1; _ksi < 6; _ksi++) { // Get a nice fractional value + float _teta = _phi * _ksi; + if (abs(_teta - round(_teta)) < 0.001) + break; + } + if (_ksi > 5) + _ksi = 1; + else + _phi *= _ksi; + + fp.align = FontProp::Align(FontProp::HorizontalAlign::left, FontProp::VerticalAlign::bottom); // correct the text position + mesh = get_text_mesh(format("%.0fcm=%.2f%%=%.4f", _ksi, _phi, _phi * 0.01).c_str(), fp, _size, + Vec3f(0., -_delta_y + _offset + _div_semiwidth, 0.), _bg); // ruler's notification + const double _rule_xmin = mesh.bounding_box().min.x(); + + mesh.translate(Vec3f(-_rule_xmin - _div_semiwidth, 0., 0.)); + test_model->add_volume(mesh); + test_model->add_volume(get_ortho_box_mesh(Vec3d(_width + _div_width, _div_width, _body_height), + Vec3f(-_div_semiwidth, -_delta_y, 0.))); // ruler's bottom line + + for (double _i = 0; _i <= _width; _i += 2.5) { + double _l = -1.; + if (_i == 0. || _i == _width) + _l = -_basedepth; + else if (!fmod(_i, 50)) + _l = -5.; + else if (!fmod(_i, 10)) + _l = -3.; + else if (!fmod(_i, 5)) + _l = -2.; + test_model->add_volume(get_ortho_box_mesh(Vec3d(_div_width, _l, _body_height), + Vec3f(_i - _div_semiwidth, -_baseline, 0.))); // ruler's dividers + } + + test_model->add_volume(get_ortho_box_mesh(Vec3d(_ksi * 10, -_div_width * 2, _body_height), + Vec3f(0., -_baseline - 5., 0.))); // ruler's scale + if (params.end > _real_fr && params.start < _real_fr) + test_model->add_volume(get_ortho_triangle_mesh(Vec3d(4., _div_width, _body_height), + Vec3f(_width / (params.end - params.start) * (_real_fr - params.start), -_baseline, 0.), 90)); // ruler's real flow pointer + } // end of print ruler + + if (params.print_numbers) { // Print scale + const double _baseline = nozzle_diameter * 5 + _depth; // baseline offset + test_model->add_volume(get_ortho_box_mesh(Vec3d(_width + _div_width, -nozzle_diameter * 4, _body_height), + Vec3f(-_div_semiwidth, _baseline, 0.))); // scale body + fp.align = FontProp::Align(FontProp::HorizontalAlign::left, FontProp::VerticalAlign::top); // correct the text position + TriangleMesh mesh = get_text_mesh(format("%.3f", params.start).c_str(), fp, _size, + Vec3f(_offset - _div_semiwidth, 0., 0.), _bg); // start scale value + const double _basedepth = mesh.bounding_box().size().y() * 2. + 5.; // ruler's base depth + const double _delta_y = _baseline + _basedepth; // y displacement + mesh.translate(Vec3f(0., _delta_y + _offset - _div_semiwidth, 0.)); + test_model->add_volume(mesh); + + fp.align = FontProp::Align(FontProp::HorizontalAlign::right, FontProp::VerticalAlign::top); // correct the text position + test_model->add_volume(get_text_mesh(format("%.3f", params.end).c_str(), fp, _size, + Vec3f(_width - _offset + _div_semiwidth, _delta_y + _offset - _div_semiwidth, 0.), _bg)); // start scale value + test_model->add_volume(get_ortho_box_mesh(Vec3d(_width + _div_width, _div_width, _body_height), + Vec3f(-_div_semiwidth, _delta_y, 0.))); // scale upper line + test_model->add_volume(get_ortho_box_mesh(Vec3d(_div_width, _basedepth, _body_height), + Vec3f(-_div_semiwidth, _baseline, 0.))); // start scale divider + test_model->add_volume(get_ortho_box_mesh(Vec3d(_div_width, _basedepth, _body_height), + Vec3f(_width - _div_semiwidth, _baseline, 0.))); // end scale divider + + fp.align = FontProp::Align(FontProp::HorizontalAlign::center, FontProp::VerticalAlign::bottom); // correct the text position + int _istart = params.start * 1000; + int _iend = params.end * 1000; + for (int _i = floor(params.start) * 1000; _i < _iend; _i++) { + if (_i > _istart) { + double _l = 0; + if (!(_i % 50)) + _l = 5; + else if (!(_i % 25)) + _l = 3; + else if (!(_i % 10)) + _l = 2; + else if (!(_i % 5)) + _l = 1; + if (_l) { + double _idbl = 0.001 * _i; + double _delta_x = _width / (params.end - params.start) * (_idbl - params.start) - _div_semiwidth; + test_model->add_volume( + get_ortho_box_mesh(Vec3d(_div_width, _l, _body_height), + Vec3f(_delta_x, _baseline, 0.))); // scale dividers + if (_l > 3) + test_model->add_volume(get_text_mesh(format("%.2f", _idbl).c_str(), fp, _size, + Vec3f(_delta_x + _div_semiwidth, _baseline + 5., 0.), + _bg)); // divider scale value + } + } + } + if (params.end > _real_fr && params.start < _real_fr) + test_model->add_volume(get_ortho_triangle_mesh(Vec3d(4., _div_width, _body_height), + Vec3f(_width / (params.end - params.start) * (_real_fr - params.start), _baseline, 0.), -90)); // scale real flow pointer + + } // end of print scale + + wxGetApp().plater()->canvas3D()->reload_scene(true); + // adjust parameters print_config->set_key_value("wall_loops", new ConfigOptionInt(1)); print_config->set_key_value("internal_bridge_density", new ConfigOptionPercent(100)); @@ -12005,9 +12215,12 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { print_config->set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true)); print_config->set_key_value("ironing_type", new ConfigOptionEnum(IroningType::NoIroning)); print_config->set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed + print_config->set_key_value("initial_layer_infill_speed", new ConfigOptionFloat(20)); print_config->set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); print_config->set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); print_config->set_key_value("fuzzy_skin", new ConfigOptionEnum(FuzzySkinType::None)); + print_config->set_key_value("wall_generator", new ConfigOptionEnum(PerimeterGeneratorType::Arachne)); + print_config->set_key_value("wall_sequence", new ConfigOptionEnum(WallSequence::InnerOuter)); print_config->set_key_value("line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); print_config->set_key_value("initial_layer_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); @@ -12018,11 +12231,6 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { print_config->set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); print_config->set_key_value("support_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); - for (auto _obj : model().objects) { - _obj->ensure_on_bed(); - _obj->name = format("Practical_FR_Test_%.2f~%.2f_%s@%fmmps", params.start, params.end, params.interlaced ? "i" : "p", params.speeds[0]); - } - print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); print_config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); print_config->set_key_value("initial_layer_print_height", new ConfigOptionFloat(first_layer_height)); @@ -12032,12 +12240,14 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{RetractLiftEnforceType::rletAllSurfaces}); printer_config->set_key_value("z_hop", new ConfigOptionFloats{params.use_zhop ? 0.4f : 0.0f}); printer_config->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtSlope}); + printer_config->set_key_value("travel_slope", new ConfigOptionFloats{45.0f}); printer_config->set_key_value("wipe_distance", new ConfigOptionFloats{0.0f}); filament_config->set_key_value("filament_z_hop", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); filament_config->set_key_value("filament_wipe_distance", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); filament_config->set_key_value("filament_retract_lift_enforce", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); filament_config->set_key_value("filament_z_hop_types", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); + //filament_config->set_key_value("travel_slope", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty(); diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index e557e37c05..b6d067380a 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -1421,17 +1421,27 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w SetForegroundColour(wxColour("#363636")); SetFont(Label::Body_14); + Bind(wxEVT_SHOW, &Practical_Flow_Ratio_Test_Dlg::on_show, this); + wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL); SetSizer(v_sizer); // Settings - wxString start_fr_str = _L("Start flowrate value at:"); - wxString end_fr_str = _L("End flowrate value at:"); - wxString quant_fr_str = _L("Number of calibration layers (4~40):"); - wxString speed_fr_str = _L("Print speed:"); - wxString interlaced_fr_str = _L("Interlaced:"); - wxString zhop_fr_str = _L("Use Z-Hop:"); - int text_max = GetTextMax(this, std::vector{start_fr_str, end_fr_str, quant_fr_str, speed_fr_str, interlaced_fr_str, zhop_fr_str}); + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; + + wxString current_fr_str = _L("Current filament flowrate:"); + wxString start_fr_str = _L("Start flowrate value at:"); + wxString end_fr_str = _L("End flowrate value at:"); + wxString quant_fr_str = _L("Number of calibration layers (4~40):"); + wxString speed_fr_str = _L("Print speed:"); + wxString interlaced_fr_str = _L("Interlaced:"); + wxString zhop_fr_str = _L("Use Z-Hop:"); + wxString scale_fr_str = _L("Print Scale:"); + wxString ruler_fr_str = _L("Print Ruler:"); + int text_max = GetTextMax(this, std::vector{current_fr_str, start_fr_str, end_fr_str, quant_fr_str, speed_fr_str, + interlaced_fr_str, zhop_fr_str, scale_fr_str, ruler_fr_str}); // Model selection auto labeled_box_model = new LabeledStaticBox(this, _L("Model width")); @@ -1450,21 +1460,19 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w auto st_size = FromDIP(wxSize(text_max, -1)); auto ti_size = FromDIP(wxSize(120, -1)); - - LabeledStaticBox* stb = new LabeledStaticBox(this, _L("Print conditions")); - wxStaticBoxSizer* settings_sizer = new wxStaticBoxSizer(stb, wxVERTICAL); - - settings_sizer->AddSpacer(FromDIP(5)); + + wxBoxSizer* fr_sizer = new wxBoxSizer(wxHORIZONTAL); + LabeledStaticBox* ctb = new LabeledStaticBox(this, _L("Print conditions")); + wxStaticBoxSizer* conditions_sizer = new wxStaticBoxSizer(ctb, wxVERTICAL); // Start flow rate value - auto fr_sizer = new wxBoxSizer(wxHORIZONTAL); - auto start_fr_text = new wxStaticText(this, wxID_ANY, start_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + auto start_fr_text = new wxStaticText(this, wxID_ANY, start_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); m_tiJDStart = new TextInput(this, wxString::Format("%.2f", 0.9), "", "", wxDefaultPosition, ti_size); m_tiJDStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); m_tiJDStart->Bind(wxEVT_TEXT, &Practical_Flow_Ratio_Test_Dlg::on_changed, this); fr_sizer->Add(start_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); fr_sizer->Add(m_tiJDStart, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); - settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + conditions_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); // End flow rate value fr_sizer = new wxBoxSizer(wxHORIZONTAL); @@ -1474,15 +1482,15 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w m_tiJDEnd->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); fr_sizer->Add(end_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); fr_sizer->Add(m_tiJDEnd, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); - settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); - settings_sizer->AddSpacer(FromDIP(5)); + conditions_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); // Add note about junction deviation - m_stNote = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + m_stNote = new wxStaticText(this, wxID_ANY, "\n\n", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); m_stNote->SetForegroundColour(wxColour(128, 128, 128)); m_stNote->SetLabel(get_status()); - settings_sizer->Add(m_stNote, 0, wxALL, FromDIP(5)); - settings_sizer->AddSpacer(FromDIP(5)); + conditions_sizer->Add(m_stNote, 0, wxEXPAND, FromDIP(5)); + conditions_sizer->AddSpacer(FromDIP(5)); // Print speed value m_tiQuantity fr_sizer = new wxBoxSizer(wxHORIZONTAL); @@ -1491,19 +1499,19 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w m_tiQuantity->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); fr_sizer->Add(quant_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); fr_sizer->Add(m_tiQuantity, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); - settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); - settings_sizer->AddSpacer(FromDIP(5)); + conditions_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); fr_sizer = new wxBoxSizer(wxHORIZONTAL); - float _speed = 60; // plater->config()->get_abs_value("outer_wall_speed"); + float _speed = 60; auto speed_fr_text = new wxStaticText(this, wxID_ANY, speed_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); m_tiSpeed = new TextInput(this, wxString::Format("%.0f", _speed), "", "", wxDefaultPosition, ti_size); m_tiSpeed->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); m_tiSpeed->SetLabel("mm/s"); fr_sizer->Add(speed_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); fr_sizer->Add(m_tiSpeed, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); - settings_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); - settings_sizer->AddSpacer(FromDIP(5)); + conditions_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); // Print settings wxBoxSizer* cb_sizer = new wxBoxSizer(wxHORIZONTAL); @@ -1512,18 +1520,37 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w m_cbInterlaced->SetValue(false); cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); cb_sizer->Add(m_cbInterlaced, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); - settings_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); - settings_sizer->AddSpacer(FromDIP(5)); + conditions_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + cb_title = new wxStaticText(this, wxID_ANY, zhop_fr_str, wxDefaultPosition, st_size, 0); m_cbUseZHop = new CheckBox(this); m_cbUseZHop->SetValue(true); cb_sizer = new wxBoxSizer(wxHORIZONTAL); cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); cb_sizer->Add(m_cbUseZHop, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); - settings_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); - settings_sizer->AddSpacer(FromDIP(5)); + conditions_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); - v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); + cb_title = new wxStaticText(this, wxID_ANY, scale_fr_str, wxDefaultPosition, st_size, 0); + m_cbPrintScale = new CheckBox(this); + m_cbPrintScale->SetValue(true); + cb_sizer = new wxBoxSizer(wxHORIZONTAL); + cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + cb_sizer->Add(m_cbPrintScale, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + + cb_title = new wxStaticText(this, wxID_ANY, ruler_fr_str, wxDefaultPosition, st_size, 0); + m_cbPrintRuler = new CheckBox(this); + m_cbPrintRuler->SetValue(true); + cb_sizer = new wxBoxSizer(wxHORIZONTAL); + cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + cb_sizer->Add(m_cbPrintRuler, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + + v_sizer->Add(conditions_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); v_sizer->AddSpacer(FromDIP(5)); auto dlg_btns = new DialogButtons(this, {"OK"}); @@ -1532,7 +1559,6 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &Practical_Flow_Ratio_Test_Dlg::on_start, this); wxGetApp().UpdateDlgDarkUI(this); - Layout(); Fit(); } @@ -1542,6 +1568,12 @@ Practical_Flow_Ratio_Test_Dlg::~Practical_Flow_Ratio_Test_Dlg() { } wxString Practical_Flow_Ratio_Test_Dlg::get_status() { + auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; + wxString addtext = "\n" + wxString::Format("%s %s filament: fr=%.3f", + filament_config->get_filament_vendor(), + filament_config->get_filament_type(), + filament_config->option("filament_flow_ratio")->get_at(0) + ).Trim(); 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); @@ -1553,16 +1585,16 @@ wxString Practical_Flow_Ratio_Test_Dlg::get_status() { float _ksi; for (_ksi = 1; _ksi < 6; _ksi++) { // Get a nice fractional value float _teta = _phi * _ksi; - if (abs(_teta - round(_teta)) < 0.01) + if (abs(_teta - round(_teta)) < 0.001) break; } if (_ksi > 5) _ksi = 1; else _phi *= _ksi; - return wxString::Format(_L("Current meas: %.0fcm = %.2f%% or %.4f"), _ksi, _phi, _phi * 0.01); + return wxString::Format(_L("Current meas: %.0fcm = %.2f%% or %.4f"), _ksi, _phi, _phi * 0.01) + addtext; } else { - return _L("The value is out of range 0.5~1.5"); + return _L("The value is out of range 0.5~1.5!"); } } @@ -1592,6 +1624,8 @@ void Practical_Flow_Ratio_Test_Dlg::on_start(wxCommandEvent& event) { m_params.model_variant = m_rbModelDepth->GetSelection(); m_params.interlaced = m_cbInterlaced->GetValue(); m_params.use_zhop = m_cbUseZHop->GetValue(); + m_params.print_numbers = m_cbPrintScale->GetValue(); + m_params.print_ruler = m_cbPrintRuler->GetValue(); double _speed; m_tiSpeed->GetTextCtrl()->GetValue().ToDouble(&_speed); m_params.speeds.clear(); @@ -1615,4 +1649,8 @@ void Practical_Flow_Ratio_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) Fit(); } +void Practical_Flow_Ratio_Test_Dlg::on_show(wxShowEvent& event) { + m_stNote->SetLabel(get_status()); +} + }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/calib_dlg.hpp b/src/slic3r/GUI/calib_dlg.hpp index d315452ace..b3112cbc28 100644 --- a/src/slic3r/GUI/calib_dlg.hpp +++ b/src/slic3r/GUI/calib_dlg.hpp @@ -193,6 +193,7 @@ protected: virtual void on_start(wxCommandEvent& event); virtual void on_changed(wxCommandEvent& event); virtual void on_changed2(wxMouseEvent& event); + virtual void on_show(wxShowEvent& event); Calib_Params m_params; RadioGroup* m_rbModel; @@ -204,6 +205,8 @@ protected: TextInput* m_tiQuantity; CheckBox* m_cbInterlaced; CheckBox* m_cbUseZHop; + CheckBox* m_cbPrintScale; + CheckBox* m_cbPrintRuler; Plater* m_plater; }; }} // namespace Slic3r::GUI From 1e09779aca97a5ea9c7af2f274027e4ff3464d7d Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Thu, 20 Nov 2025 09:48:01 +0300 Subject: [PATCH 10/19] Update config --- src/slic3r/GUI/Plater.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d0200fd4d4..96eb458e2f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -12521,7 +12521,12 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { print_config->set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); print_config->set_key_value("infill_direction", new ConfigOptionFloat(0)); print_config->set_key_value("internal_solid_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); + print_config->set_key_value("infill_combination", new ConfigOptionBool(false)); print_config->set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true)); + print_config->set_key_value("precise_outer_wall", new ConfigOptionBool(false)); + print_config->set_key_value("precise_z_height", new ConfigOptionBool(false)); + print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); + print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false)); print_config->set_key_value("ironing_type", new ConfigOptionEnum(IroningType::NoIroning)); print_config->set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed print_config->set_key_value("initial_layer_infill_speed", new ConfigOptionFloat(20)); @@ -12546,7 +12551,7 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); print_config->set_key_value("reduce_crossing_wall", new ConfigOptionBool(true)); - printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{RetractLiftEnforceType::rletAllSurfaces}); + printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{params.use_zhop ? RetractLiftEnforceType::rletBottomOnly : RetractLiftEnforceType::rletBottomOnly}); printer_config->set_key_value("z_hop", new ConfigOptionFloats{params.use_zhop ? 0.4f : 0.0f}); printer_config->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtSlope}); printer_config->set_key_value("travel_slope", new ConfigOptionFloats{45.0f}); From 79f0938f74aaa29e9ab9b90df395e5dbcddab948 Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Sun, 23 Nov 2025 15:51:12 +0300 Subject: [PATCH 11/19] zHop updates --- src/slic3r/GUI/Plater.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 96eb458e2f..ce70474592 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -12551,9 +12551,11 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); print_config->set_key_value("reduce_crossing_wall", new ConfigOptionBool(true)); - printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{params.use_zhop ? RetractLiftEnforceType::rletBottomOnly : RetractLiftEnforceType::rletBottomOnly}); + printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{params.use_zhop ? RetractLiftEnforceType::rletAllSurfaces : RetractLiftEnforceType::rletBottomOnly}); printer_config->set_key_value("z_hop", new ConfigOptionFloats{params.use_zhop ? 0.4f : 0.0f}); printer_config->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtSlope}); + printer_config->set_key_value("retract_lift_above", new ConfigOptionFloats{0.0f}); + printer_config->set_key_value("retract_lift_below", new ConfigOptionFloats{100.0f}); printer_config->set_key_value("travel_slope", new ConfigOptionFloats{45.0f}); printer_config->set_key_value("wipe_distance", new ConfigOptionFloats{0.0f}); From 61a898912581482163a77d4cb183d4d3d97dd9e4 Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 25 Nov 2025 03:41:47 +0300 Subject: [PATCH 12/19] finally done --- src/slic3r/GUI/Plater.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ce70474592..d05fd47801 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -12356,12 +12356,13 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { string _name = format("Practical_FR_Test_%.2f~%.2f_@%.0f%s", params.start, params.end, params.speeds[0], params.interlaced ? "i" : "p"); - const auto bed_shape = printer_config->option("printable_area")->values; - const BoundingBoxf bed_ext = get_extents(bed_shape); - const Vec2d _center = bed_ext.center(); + const auto bed_shape = printer_config->option("printable_area")->values; + const BoundingBoxf bed_ext = get_extents(bed_shape); + const Vec2d _center = bed_ext.center(); + const double _model_height = zscale * 1.2; auto test_model = model().add_object(); - TriangleMesh its_model = TriangleMesh(make_cube(xscale * 100, yscale * 10, zscale * 1.2)); + TriangleMesh its_model = TriangleMesh(make_cube(xscale * 100, yscale * 10, _model_height)); test_model->name = _name; test_model->add_volume(its_model); test_model->add_instance(); @@ -12504,10 +12505,11 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { print_config->set_key_value("min_width_top_surface", new ConfigOptionFloatOrPercent(100, true)); print_config->set_key_value("only_one_wall_top", new ConfigOptionBool(true)); print_config->set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f)); - print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0)); + print_config->set_key_value("top_shell_layers", new ConfigOptionInt(1)); print_config->set_key_value("top_surface_pattern", new ConfigOptionEnum(ipMonotonicLine)); print_config->set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f)); print_config->set_key_value("top_shell_thickness", new ConfigOptionFloat(0)); + print_config->set_key_value("top_surface_density", new ConfigOptionPercent(100)); print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(2)); print_config->set_key_value("bottom_surface_pattern", new ConfigOptionEnum(ipMonotonic)); print_config->set_key_value("bottom_shell_thickness", new ConfigOptionFloat(0)); @@ -12551,11 +12553,12 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); print_config->set_key_value("reduce_crossing_wall", new ConfigOptionBool(true)); - printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{params.use_zhop ? RetractLiftEnforceType::rletAllSurfaces : RetractLiftEnforceType::rletBottomOnly}); + printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{params.use_zhop ? RetractLiftEnforceType::rletTopAndBottom : RetractLiftEnforceType::rletBottomOnly}); printer_config->set_key_value("z_hop", new ConfigOptionFloats{params.use_zhop ? 0.4f : 0.0f}); - printer_config->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtSlope}); - printer_config->set_key_value("retract_lift_above", new ConfigOptionFloats{0.0f}); - printer_config->set_key_value("retract_lift_below", new ConfigOptionFloats{100.0f}); + printer_config->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtNormal}); + printer_config->set_key_value("retraction_minimum_travel", new ConfigOptionFloats{5.0f}); + printer_config->set_key_value("retract_lift_above", new ConfigOptionFloats{0.f}); //_model_height - first_layer_height + printer_config->set_key_value("retract_lift_below", new ConfigOptionFloats{100.f}); //layer_height printer_config->set_key_value("travel_slope", new ConfigOptionFloats{45.0f}); printer_config->set_key_value("wipe_distance", new ConfigOptionFloats{0.0f}); @@ -12563,7 +12566,10 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { filament_config->set_key_value("filament_wipe_distance", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); filament_config->set_key_value("filament_retract_lift_enforce", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); filament_config->set_key_value("filament_z_hop_types", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); - //filament_config->set_key_value("travel_slope", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + filament_config->set_key_value("filament_retraction_minimum_travel", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + filament_config->set_key_value("filament_retract_lift_above", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + filament_config->set_key_value("filament_retract_lift_below", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + //filament_config->set_key_value("filament_travel_slope", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty(); From fa3ba9a5100eb3ccb7c22e46b4e3cc92aa0fe37f Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 25 Nov 2025 23:44:20 +0300 Subject: [PATCH 13/19] some corrections --- src/slic3r/GUI/Plater.cpp | 3 ++- src/slic3r/GUI/calib_dlg.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d05fd47801..49114d8092 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -12530,8 +12530,9 @@ void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false)); print_config->set_key_value("ironing_type", new ConfigOptionEnum(IroningType::NoIroning)); + print_config->set_key_value("top_surface_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed print_config->set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed - print_config->set_key_value("initial_layer_infill_speed", new ConfigOptionFloat(20)); + //print_config->set_key_value("initial_layer_infill_speed", new ConfigOptionFloat(20)); print_config->set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); print_config->set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); print_config->set_key_value("fuzzy_skin", new ConfigOptionEnum(FuzzySkinType::None)); diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index 28e6bf6416..ed30fa480e 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -1607,7 +1607,7 @@ void Practical_Flow_Ratio_Test_Dlg::on_start(wxCommandEvent& event) { MessageDialog msg_dlg(nullptr, _L("Please input valid values:\n(0.5 <= Flow Ratio <= 1.5)"), wxEmptyString, wxICON_WARNING | wxOK); msg_dlg.ShowModal(); return; - } else if (!m_tiQuantity->GetTextCtrl()->GetValue().ToDouble(&m_params.step) || m_params.step < 4 || m_params.step > 20) { + } else if (!m_tiQuantity->GetTextCtrl()->GetValue().ToDouble(&m_params.step) || m_params.step < 4 || m_params.step > 40) { MessageDialog msg_dlg(nullptr, _L("Please input valid layer value:\n(4 <= Number of Calibration Layers <= 40)"), wxEmptyString, wxICON_WARNING | wxOK); msg_dlg.ShowModal(); return; From b3a196af299eb29a48e1aa1590101b6c28ec710a Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 9 Dec 2025 04:23:15 +0300 Subject: [PATCH 14/19] fix build / add usabilities --- src/libslic3r/Fill/FillBase.cpp | 17 +++++++++++------ src/slic3r/GUI/calib_dlg.cpp | 8 ++++---- src/slic3r/GUI/calib_dlg.hpp | 2 +- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 170f2923ce..26215b6be0 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -174,7 +174,6 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para case CalibMode::Calib_Practical_Flow_Ratio: if (layer_id > 3) eec->no_sort = true; - //params.density = 0.5; } } @@ -236,18 +235,24 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para for (ExtrusionPath* _p : b) eec->entities.emplace_back(_p); } + } else if (layer_id == 3) { + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + _p->width *= 0.825; + _p->mm3_per_mm *= 0.825; + } } else if (layer_id > 0) { // Prepare a smooth base std::vector a; - int _i = 1; + int _i = 1; for (ExtrusionEntity* e : eec->entities) { ExtrusionPath* _p = static_cast(e); if (++_i % 2) { if ((_i / 2) % 2) _p->reverse(); - if (layer_id == 1) { - _p->width *= 0.75; - _p->mm3_per_mm *= 0.75; - } + //if (layer_id == 1) { + // _p->width *= 0.75; + // _p->mm3_per_mm *= 0.75; + //} a.emplace_back(_p); } } diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index ed30fa480e..a8b7b84719 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -1437,7 +1437,7 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w wxString quant_fr_str = _L("Number of calibration layers (4~40):"); wxString speed_fr_str = _L("Print speed:"); wxString interlaced_fr_str = _L("Interlaced:"); - wxString zhop_fr_str = _L("Use Z-Hop:"); + wxString zhop_fr_str = _L("Use Z-Hop at top surface:"); wxString scale_fr_str = _L("Print Scale:"); wxString ruler_fr_str = _L("Print Ruler:"); int text_max = GetTextMax(this, std::vector{current_fr_str, start_fr_str, end_fr_str, quant_fr_str, speed_fr_str, @@ -1525,7 +1525,7 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w cb_title = new wxStaticText(this, wxID_ANY, zhop_fr_str, wxDefaultPosition, st_size, 0); m_cbUseZHop = new CheckBox(this); - m_cbUseZHop->SetValue(true); + m_cbUseZHop->SetValue(false); cb_sizer = new wxBoxSizer(wxHORIZONTAL); cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); cb_sizer->Add(m_cbUseZHop, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -1534,7 +1534,7 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w cb_title = new wxStaticText(this, wxID_ANY, scale_fr_str, wxDefaultPosition, st_size, 0); m_cbPrintScale = new CheckBox(this); - m_cbPrintScale->SetValue(true); + m_cbPrintScale->SetValue(false); cb_sizer = new wxBoxSizer(wxHORIZONTAL); cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); cb_sizer->Add(m_cbPrintScale, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -1543,7 +1543,7 @@ Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, w cb_title = new wxStaticText(this, wxID_ANY, ruler_fr_str, wxDefaultPosition, st_size, 0); m_cbPrintRuler = new CheckBox(this); - m_cbPrintRuler->SetValue(true); + m_cbPrintRuler->SetValue(false); cb_sizer = new wxBoxSizer(wxHORIZONTAL); cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); cb_sizer->Add(m_cbPrintRuler, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); diff --git a/src/slic3r/GUI/calib_dlg.hpp b/src/slic3r/GUI/calib_dlg.hpp index b3112cbc28..59083205fa 100644 --- a/src/slic3r/GUI/calib_dlg.hpp +++ b/src/slic3r/GUI/calib_dlg.hpp @@ -187,7 +187,7 @@ public: Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater); ~Practical_Flow_Ratio_Test_Dlg(); void on_dpi_changed(const wxRect& suggested_rect) override; - wxString Practical_Flow_Ratio_Test_Dlg::get_status(); + wxString get_status(); protected: virtual void on_start(wxCommandEvent& event); From b7e020c8bf09b59c63d2bfdd023bd75926c119a5 Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 9 Dec 2025 10:22:44 +0300 Subject: [PATCH 15/19] fix --- src/slic3r/GUI/Plater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 49114d8092..e287a96302 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -231,7 +231,7 @@ Emboss::FontFileWithCache calib_font_with_cache(std::move(WxFontUtils::create_fo /// "y" is the font height in millimeters. /// "z" is the height of the extruded text in millimeters. /// Position of model against text pivot. -static TriangleMesh get_ortho_box_mesh(Vec3d& size, Vec3f& position = Vec3f()) +static TriangleMesh get_ortho_box_mesh(Vec3d size, Vec3f position = Vec3f()) { TriangleMesh mesh(make_cube(size.x(), size.y(), size.z())); // get box mesh.translate(position); // move mesh to indeed place From 02a8c468c227f14da0c7108173b0876056bf84e5 Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 9 Dec 2025 17:33:47 +0300 Subject: [PATCH 16/19] fix 2 --- src/slic3r/GUI/Plater.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e287a96302..64b6e78a74 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -247,7 +247,7 @@ static TriangleMesh get_ortho_box_mesh(Vec3d size, Vec3f position = Vec3f()) /// "z" is the height of the extruded shape in millimeters. /// Position of model against its pivot. /// Rotation angle of model against its pivot. -static TriangleMesh get_ortho_triangle_mesh(Vec3d &size, Vec3f &position = Vec3f(), double rotation = 0.) +static TriangleMesh get_ortho_triangle_mesh(Vec3d size, Vec3f position = Vec3f(), double rotation = 0.) { TriangleMesh mesh(make_cube(size.y(), size.x(), size.z())); // get triangle side double _ypos = size.x() * sin(PI / 3); @@ -278,7 +278,7 @@ static TriangleMesh get_ortho_triangle_mesh(Vec3d &size, Vec3f &position = Vec3f /// Place background box under text {depth, offset} /// "depth" is the depth of the background box. Its height is added to the height of the entire model. /// "offset" external expansion relative to the borders of the text. -static TriangleMesh get_text_mesh(const char *text, FontProp &font_props, Vec3d &size, Vec3f &position = Vec3f(), Vec2f &background = Vec2f()) +static TriangleMesh get_text_mesh(const char *text, FontProp &font_props, Vec3d size, Vec3f position = Vec3f(), Vec2f &background = Vec2f()) { TriangleMesh mesh( Emboss::text2model(calib_font_with_cache, text, font_props, Vec3d(size.x(), size.y(), size.z() + background.x()))); // get text mesh From 5a2076eee36d6b4a201f31f0bbe8a84b7c4ea2ea Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 9 Dec 2025 18:17:15 +0300 Subject: [PATCH 17/19] fix 3 --- src/slic3r/GUI/Plater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 64b6e78a74..1dc06f58e1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -278,7 +278,7 @@ static TriangleMesh get_ortho_triangle_mesh(Vec3d size, Vec3f position = Vec3f() /// Place background box under text {depth, offset} /// "depth" is the depth of the background box. Its height is added to the height of the entire model. /// "offset" external expansion relative to the borders of the text. -static TriangleMesh get_text_mesh(const char *text, FontProp &font_props, Vec3d size, Vec3f position = Vec3f(), Vec2f &background = Vec2f()) +static TriangleMesh get_text_mesh(const char *text, FontProp &font_props, Vec3d size, Vec3f position = Vec3f(), Vec2f background = Vec2f()) { TriangleMesh mesh( Emboss::text2model(calib_font_with_cache, text, font_props, Vec3d(size.x(), size.y(), size.z() + background.x()))); // get text mesh From 0fc8342171f606487884148aa4bd72f065df06d4 Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 9 Dec 2025 18:57:02 +0300 Subject: [PATCH 18/19] fix 4 --- src/libslic3r/Emboss.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Emboss.cpp b/src/libslic3r/Emboss.cpp index af9f6404ec..e28605d48f 100644 --- a/src/libslic3r/Emboss.cpp +++ b/src/libslic3r/Emboss.cpp @@ -1299,7 +1299,7 @@ HealedExPolygons Emboss::text2shapes(FontFileWithCache &font_with_cache, const c return ::union_with_delta(vshapes, delta, MAX_HEAL_ITERATION_OF_TEXT); } -indexed_triangle_set Emboss::text2model(FontFileWithCache &font, const char *text, const FontProp &font_prop, Vec3d &dx_y_z_size) +indexed_triangle_set Emboss::text2model(FontFileWithCache &font, const char *text, const FontProp &font_prop, Vec3d dx_y_z_size) { const double scale = 0.000001 * 25.4 / 72 * dx_y_z_size.y(); // convert points to millimeters (represent interliniage) const double width = dx_y_z_size.x() ? dx_y_z_size.x() : 1.0; From 5a464344d29348a5ab2ea1b0e9d35be32a74c1a0 Mon Sep 17 00:00:00 2001 From: pi-squared-studio Date: Tue, 9 Dec 2025 19:24:01 +0300 Subject: [PATCH 19/19] fix 4 --- src/libslic3r/Emboss.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Emboss.hpp b/src/libslic3r/Emboss.hpp index 2791cbfb20..9c3a7a5c73 100644 --- a/src/libslic3r/Emboss.hpp +++ b/src/libslic3r/Emboss.hpp @@ -163,7 +163,7 @@ namespace Emboss /// User defined property of the font /// The size of the printed text {dx, y, z}. "dx" is the width of the character relative to its size (default is 1.0). "y" is the font height in millimeters. "z"S is the height of the extruded text in millimeters. /// Indexed triangle set - indexed_triangle_set text2model(FontFileWithCache& font, const char *text, const FontProp &font_prop, Vec3d &dx_y_z_size); + indexed_triangle_set text2model(FontFileWithCache& font, const char *text, const FontProp &font_prop, Vec3d dx_y_z_size); const unsigned ENTER_UNICODE = static_cast('\n'); /// Sum of character '\n'