diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index 507c65f7bb..e7facbdbd8 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -5527,12 +5527,28 @@ int CLI::run(int argc, char **argv) //add the virtual object into unselect list if has partplate_list.preprocess_exclude_areas(unselected, enable_wrapping_detect); - if (used_filament_set.size() > 0) + // Filament ids given on the command line size the tower for STL input. A project + // records its filament use per plate, so count there and keep its tower positions. + const int plate_count = partplate_list.get_plate_count(); + const bool from_project = used_filament_set.empty(); + std::vector plate_filament_counts(plate_count, static_cast(used_filament_set.size())); + if (from_project) + for (int plate_index = 0; plate_index < plate_count; ++plate_index) + plate_filament_counts[plate_index] = static_cast(partplate_list.get_plate(plate_index)->get_extruders_under_cli(true, m_print_config).size()); + // A project only gets a tower the slicer will print: the prime tower enabled, and not + // a by-object print unless a smooth timelapse needs it, as the per-plate arrange decides. + const bool project_tower_allowed = m_print_config.option("enable_prime_tower", true)->value && + (is_smooth_timelapse || !arrange_cfg.is_seq_print); + const auto plate_needs_wipe_tower = [from_project, project_tower_allowed, is_smooth_timelapse](int filament_count) { + if (!from_project) + return filament_count > 0; + return project_tower_allowed && (filament_count > 1 || (filament_count > 0 && is_smooth_timelapse)); + }; + const int max_filament_count = plate_count > 0 ? *std::max_element(plate_filament_counts.begin(), plate_filament_counts.end()) : 0; + + if (plate_needs_wipe_tower(max_filament_count)) { //prepare the wipe tower - int plate_count = partplate_list.get_plate_count(); - int extruder_size = used_filament_set.size(); - auto printer_structure_opt = m_print_config.option>("printer_structure"); // This margin only pre-adjusts the default away from the near edges; // estimate_wipe_tower_polygon below computes the real clamped position. @@ -5568,7 +5584,11 @@ int CLI::run(int argc, char **argv) for (int bedid = 0; bedid < MAX_PLATE_COUNT; bedid++) { int plate_index_valid = std::min(bedid, plate_count - 1); - if (bedid < plate_count) { + // Overflow beds may receive objects from any plate, so size them for the busiest one. + const int extruder_size = bedid < plate_count ? plate_filament_counts[bedid] : max_filament_count; + if (!plate_needs_wipe_tower(extruder_size)) + continue; + if (bedid < plate_count && !from_project) { wipe_x_option->set_at(&wt_x_opt, plate_index_valid, 0); wipe_y_option->set_at(&wt_y_opt, plate_index_valid, 0); }