From 431e5e3f126baf2555370013f35b0d9f034d408c Mon Sep 17 00:00:00 2001 From: Benik3 Date: Wed, 8 Oct 2025 22:05:34 +0200 Subject: [PATCH 1/3] improve flow calibration with monotonic lines - print the lines always in one direction - print from two sides into a center of the objects --- src/libslic3r/Fill/FillRectilinear.cpp | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 4138ef0511..570cf036ab 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -2874,6 +2874,55 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa traverse_graph_generate_polylines(poly_with_offset, params, segs, this->has_consistent_pattern(), polylines_out); } + // Check if we're in flow calibration mode + bool is_flow_calibration = 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() && + params.monotonic; + + if (is_flow_calibration && !polylines_out.empty()) { + // Get the range of newly added polylines + auto start_it = polylines_out.begin() + n_polylines_out_initial; + auto end_it = polylines_out.end(); + + if (start_it != end_it) { + // 1) For sure sort lines by X of the midpoint so lines are ordered left-to-right across objects. + std::stable_sort(start_it, end_it, [](const Polyline& a, const Polyline& b) { + // Midpoint X as average of endpoints + auto ax = (int64_t) a.points.front().x() + (int64_t) a.points.back().x(); + auto bx = (int64_t) b.points.front().x() + (int64_t) b.points.back().x(); + if (ax == bx) { + // Tiebreaker by midpoint Y, then by start X to stabilize order + auto ay = (int64_t) a.points.front().y() + (int64_t) a.points.back().y(); + auto by = (int64_t) b.points.front().y() + (int64_t) b.points.back().y(); + if (ay == by) + return a.points.front().x() < b.points.front().x(); + return ay < by; + } + return ax < bx; + }); + + // 2) Normalize direction: make every polyline point "up-right". + for (auto it = start_it; it != end_it; ++it) { + if (it->points.empty()) + continue; + const Point& p0 = it->points.front(); + const Point& p1 = it->points.back(); + auto vec = (p1 - p0).template cast(); + double dir = vec.x() + vec.y(); + if (dir < 0.0) { + std::reverse(it->points.begin(), it->points.end()); + } + } + + // 3) Split into halves and reverse order of the 2nd half so it prints towards the 1st half. + size_t total = std::distance(start_it, end_it); + size_t mid = total / 2; + auto mid_it = start_it + mid; + std::reverse(mid_it, end_it); + } + } + #ifdef SLIC3R_DEBUG { { From 0cfb80d04493931922004c17b8d214668fc173e5 Mon Sep 17 00:00:00 2001 From: Benik3 Date: Wed, 5 Nov 2025 21:47:30 +0100 Subject: [PATCH 2/3] disable z-hop and retract wipe and use 75% of the max volumetric flow speed --- src/slic3r/GUI/Plater.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d9c95d6d06..a89910cb49 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -9892,7 +9892,8 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i auto cur_flowrate = filament_config->option("filament_flow_ratio")->get_at(0); Flow infill_flow = Flow(nozzle_diameter * 1.2f, layer_height, nozzle_diameter); - double filament_max_volumetric_speed = filament_config->option("filament_max_volumetric_speed")->get_at(0); + // for sure, use max volumetric flow of 75% of the current setting to prevent underflow near the limit of the nozzle + double filament_max_volumetric_speed = filament_config->option("filament_max_volumetric_speed")->get_at(0) * 0.75; double max_infill_speed; if (linear) max_infill_speed = filament_max_volumetric_speed / @@ -9902,6 +9903,17 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i double internal_solid_speed = std::floor(std::min(print_config->opt_float("internal_solid_infill_speed"), max_infill_speed)); double top_surface_speed = std::floor(std::min(print_config->opt_float("top_surface_speed"), max_infill_speed)); + // disable z-hop and retract wipe + 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()}); + + printerConfig->set_key_value("z_hop", new ConfigOptionFloats{0.0f}); + printerConfig->set_key_value("wipe_distance", new ConfigOptionFloats{0.0f}); + printerConfig->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{RetractLiftEnforceType::rletAllSurfaces}); + printerConfig->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtNormal}); + // adjust parameters for (auto _obj : objects) { _obj->ensure_on_bed(); From 91301d23de8fff0a170ce0c3263d79073916d42f Mon Sep 17 00:00:00 2001 From: Benik3 Date: Wed, 3 Dec 2025 20:53:12 +0100 Subject: [PATCH 3/3] Change flow calibration pattern to Monotonic line --- 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 ce2595d484..8f0847c667 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -12318,7 +12318,7 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i _obj->config.set_key_value("sparse_infill_pattern", new ConfigOptionEnum(ipRectilinear)); _obj->config.set_key_value("top_surface_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter * 1.2f, false)); _obj->config.set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter * 1.2f, false)); - _obj->config.set_key_value("top_surface_pattern", new ConfigOptionEnum(ipArchimedeanChords)); + _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("infill_direction", new ConfigOptionFloat(45)); _obj->config.set_key_value("solid_infill_direction", new ConfigOptionFloat(135));