Calibrations improvements (#14759)

This commit is contained in:
Ian Bassi
2026-07-27 20:11:44 -03:00
committed by GitHub
parent 33dfb66aa5
commit 6bcb809dd0
6 changed files with 284 additions and 32 deletions
+31 -3
View File
@@ -1265,6 +1265,19 @@ void CalibUtils::calib_VFA(const CalibInfo &calib_info, wxString &error_message)
DynamicPrintConfig filament_config = calib_info.filament_prest->config;
DynamicPrintConfig printer_config = calib_info.printer_prest->config;
const ConfigOptionFloats* nozzle_diameter_config = printer_config.option<ConfigOptionFloats>("nozzle_diameter");
size_t nozzle_id = static_cast<size_t>(std::max(params.extruder_id, 0));
double nozzle_diameter = vfa_base_nozzle_diameter;
if (nozzle_diameter_config && !nozzle_diameter_config->values.empty()) {
nozzle_id = std::min(nozzle_id, nozzle_diameter_config->values.size() - 1);
nozzle_diameter = nozzle_diameter_config->values[nozzle_id];
}
if (nozzle_diameter <= 0.0)
nozzle_diameter = vfa_base_nozzle_diameter;
// Resolved layer height: use the (possibly auto-adjusted) value if provided, else default to nozzle/2.
double layer_height = params.vfa_layer_height > 0.0 ? params.vfa_layer_height : nozzle_diameter / 2.0;
filament_config.set_key_value("slow_down_layer_time", new ConfigOptionInts{0});
filament_config.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{200});
filament_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(calib_info.bed_type));
@@ -1280,13 +1293,18 @@ void CalibUtils::calib_VFA(const CalibInfo &calib_info, wxString &error_message)
print_config.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
print_config.set_key_value("overhang_reverse", new ConfigOptionBool(false));
print_config.set_key_value("spiral_mode", new ConfigOptionBool(true));
print_config.set_key_value("initial_layer_print_height", new ConfigOptionFloat(layer_height));
model.objects[0]->config.set_key_value("layer_height", new ConfigOptionFloat(layer_height));
model.objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
model.objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0));
model.objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
// cut upper
// cut upper (on the unscaled model, using the base block height); the scaling below keeps the physical
// block height (vfa_layers_per_block * layer_height) in sync with the speed stepping in GCode::process_layer.
// Subtract EPSILON (as the temperature tower does) so the cut lands just below the flat block surface instead
// of exactly on it, which would otherwise add a degenerate extra layer.
auto obj_bb = model.objects[0]->bounding_box_exact();
auto height = 5 * ((params.end - params.start) / params.step + 1);
auto height = vfa_base_block_height * ((params.end - params.start) / params.step + 1) - EPSILON;
if (height < obj_bb.size().z()) {
cut_model(model, height, ModelObjectCutAttribute::KeepLower);
}
@@ -1295,6 +1313,13 @@ void CalibUtils::calib_VFA(const CalibInfo &calib_info, wxString &error_message)
return;
}
// XY scales with the nozzle; Z scales so each base block becomes vfa_layers_per_block layers of layer_height.
const double xy_scale = nozzle_diameter / vfa_base_nozzle_diameter;
const double z_scale = (vfa_layers_per_block * layer_height) / vfa_base_block_height;
if (std::abs(xy_scale - 1.0) > EPSILON || std::abs(z_scale - 1.0) > EPSILON)
model.objects[0]->scale(xy_scale, xy_scale, z_scale);
model.objects[0]->ensure_on_bed();
DynamicPrintConfig full_config;
full_config.apply(FullPrintConfig::defaults());
full_config.apply(print_config);
@@ -1303,7 +1328,10 @@ void CalibUtils::calib_VFA(const CalibInfo &calib_info, wxString &error_message)
init_multi_extruder_params_for_cali(full_config, calib_info);
process_and_store_3mf(&model, full_config, params, error_message);
// Pass the resolved layer height on so the GCode speed stepping matches the geometry.
Calib_Params store_params = params;
store_params.vfa_layer_height = layer_height;
process_and_store_3mf(&model, full_config, store_params, error_message);
if (!error_message.empty())
return;