Restore flow calibration special order, overridable via fill order (#14786)

This commit is contained in:
Mqrius
2026-07-16 14:10:15 +02:00
committed by GitHub
parent 5e7ad1ad70
commit 6d1974a662
6 changed files with 51 additions and 8 deletions

View File

@@ -162,11 +162,14 @@ 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_flowrate_topinfill_special_order") &&
this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool();
// Orca: a forced surface fill order must survive the G-code path planner, which would
// otherwise re-chain and possibly reverse the paths. This also covers the flow rate
// calibration, which forces an outward fill order on its top surfaces.
// otherwise re-chain and possibly reverse the paths. The same applies to the flow rate
// calibration's special toolpath order.
const bool keep_fill_order = params.fill_order != SurfaceFillOrder::Default;
if (keep_fill_order) {
if (is_flow_calib || keep_fill_order) {
eec->no_sort = true;
}
size_t idx = eec->entities.size();
@@ -181,7 +184,7 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para
params.extrusion_role,
flow_mm3_per_mm, float(flow_width), params.flow.height());
}
if (!params.can_reverse || keep_fill_order) {
if (!params.can_reverse || is_flow_calib || keep_fill_order) {
for (size_t i = idx; i < eec->entities.size(); i++)
eec->entities[i]->set_reverse();
}

View File

@@ -134,7 +134,34 @@ void FillPlanePath::_fill_surface_single(
if (!polylines.empty()) {
Polylines chained;
if (params.dont_connect() || params.density > 0.5) {
if (params.fill_order != SurfaceFillOrder::Default) {
// ORCA: special flag for flow rate calibration. The chords chained ahead of the
// inside-out center spiral collide with it in opposing directions, raising a
// tactile lip that the calibration reads. Only applies while the fill order is
// Default, so it can be overridden from the calibration objects.
auto is_flow_calib = params.fill_order == SurfaceFillOrder::Default &&
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() &&
dynamic_cast<FillArchimedeanChords*>(this);
if (is_flow_calib) {
// We want the spiral part to be printed inside-out
// Find the center spiral line first, by looking for the longest one
auto it = std::max_element(polylines.begin(), polylines.end(),
[](const Polyline& a, const Polyline& b) { return a.length() < b.length(); });
Polyline center_spiral = std::move(*it);
// Ensure the spiral is printed from inside to out
if (center_spiral.first_point().squaredNorm() > center_spiral.last_point().squaredNorm()) {
center_spiral.reverse();
}
// Chain the other polylines
polylines.erase(it);
chained = chain_polylines(std::move(polylines), nullptr);
// Then add the center spiral back
chained.push_back(std::move(center_spiral));
} else if (params.fill_order != SurfaceFillOrder::Default) {
// Orca: print the fragments in the order they appear along the generated
// path, which runs from the center outwards. The Euclidean distance from
// the center cannot be used for this: along the Octagram Spiral the radius

View File

@@ -1310,6 +1310,7 @@ static std::vector<std::string> s_Preset_print_options{
"interlocking_depth",
"interlocking_boundary_avoidance",
"interlocking_beam_width",
"calib_flowrate_topinfill_special_order",
// Z Anti-Aliasing (ZAA)
"zaa_enabled",
"zaa_minimize_perimeter_height",

View File

@@ -4647,6 +4647,11 @@ 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));
def = this->add("ironing_type", coEnum);
def->label = L("Ironing type");
def->category = L("Quality");
@@ -9016,7 +9021,6 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
"internal_bridge_support_thickness", "top_area_threshold", "reduce_wall_solid_infill","filament_load_time","filament_unload_time",
"smooth_coefficient", "overhang_totally_speed", "silent_mode",
"overhang_speed_classic", "filament_prime_volume",
"calib_flowrate_topinfill_special_order",
"anisotropic_surfaces", // superseded by top_surface_fill_order / bottom_surface_fill_order
};

View File

@@ -1221,6 +1221,9 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionInt, interlocking_beam_layer_count))
((ConfigOptionInt, interlocking_depth))
((ConfigOptionInt, interlocking_boundary_avoidance))
// Orca: internal use only
((ConfigOptionBool, calib_flowrate_topinfill_special_order)) // ORCA: special flag for flow rate calibration
)
// This object is mapped to Perl as Slic3r::Config::PrintRegion.

View File

@@ -13929,8 +13929,13 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i
_obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None));
_obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum<GapFillTarget>(GapFillTarget::gftNowhere));
print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0));
// ORCA: print the top surface spiral from the center outwards, so the tiles are comparable.
_obj->config.set_key_value("top_surface_fill_order", new ConfigOptionEnum<SurfaceFillOrder>(SurfaceFillOrder::Outward));
// ORCA: request the calibration's special toolpath order (chords first, center spiral
// last and inside-out) so opposing directions collide into the tactile lip the test
// reads. The special order only applies while the fill order is Default, so reset the
// profile's fill order on the calibration objects; changing the setting on the object
// afterwards deliberately overrides the special order.
_obj->config.set_key_value("calib_flowrate_topinfill_special_order", new ConfigOptionBool(true));
_obj->config.set_key_value("top_surface_fill_order", new ConfigOptionEnum<SurfaceFillOrder>(SurfaceFillOrder::Default));
// extract flowrate from name, filename format: flowrate_xxx
std::string obj_name = _obj->name;