Fix CLI wipe-tower position silently reused across plates when the array is undersized

This commit is contained in:
Hanif Koh
2026-08-27 17:43:02 +08:00
parent 594e7c55c9
commit 92b394fe4e

View File

@@ -3951,6 +3951,13 @@ int CLI::run(int argc, char **argv)
ConfigOptionFloats *wipe_x_option = dynamic_cast<ConfigOptionFloats *>(print_config.option("wipe_tower_x"));
ConfigOptionFloats *wipe_y_option = dynamic_cast<ConfigOptionFloats *>(print_config.option("wipe_tower_y"));
// get_at() clamps an out-of-range index to entry 0 instead of erroring, which
// would silently reuse another plate's wipe tower position here. Warn so a mismatched
// wipe_tower_x/y array (e.g. from a project saved before this plate was added) is visible.
if (static_cast<size_t>(plate_index) >= wipe_x_option->values.size() || static_cast<size_t>(plate_index) >= wipe_y_option->values.size()) {
BOOST_LOG_TRIVIAL(warning) << boost::format("plate %1%: wipe_tower_x/y only has %2%/%3% entries, reusing entry 0's position")
%(plate_index+1) %wipe_x_option->values.size() %wipe_y_option->values.size();
}
plate_obj_size_info.wipe_x = wipe_x_option->get_at(plate_index);
plate_obj_size_info.wipe_y = wipe_y_option->get_at(plate_index);
@@ -5541,6 +5548,26 @@ int CLI::run(int argc, char **argv)
}
finished_arrange = true;
}
// CLI has no m_plater, so PartPlateList::create_plate() never backfills
// wipe_tower_x/y for plates created here during arrange overflow (unlike GUI's
// set_default_wipe_tower_pos_for_plate()). Keep both arrays sized to the actual
// plate count so a later per-plate get_at() never silently reuses another plate's
// wipe tower position via ConfigOptionVector's out-of-range clamp.
{
int final_plate_count = partplate_list.get_plate_count();
ConfigOptionFloats* wipe_x_opt = m_print_config.option<ConfigOptionFloats>("wipe_tower_x");
ConfigOptionFloats* wipe_y_opt = m_print_config.option<ConfigOptionFloats>("wipe_tower_y");
if (wipe_x_opt && !wipe_x_opt->values.empty() && wipe_x_opt->values.size() < static_cast<size_t>(final_plate_count)) {
BOOST_LOG_TRIVIAL(info) << boost::format("wipe_tower_x had %1% entries for %2% plates, backfilling with entry 0")
% wipe_x_opt->values.size() % final_plate_count;
wipe_x_opt->values.resize(final_plate_count, wipe_x_opt->values.front());
}
if (wipe_y_opt && !wipe_y_opt->values.empty() && wipe_y_opt->values.size() < static_cast<size_t>(final_plate_count)) {
BOOST_LOG_TRIVIAL(info) << boost::format("wipe_tower_y had %1% entries for %2% plates, backfilling with entry 0")
% wipe_y_opt->values.size() % final_plate_count;
wipe_y_opt->values.resize(final_plate_count, wipe_y_opt->values.front());
}
}
original_model.clear_objects();
original_model.clear_materials();
}