Size a no-purge tower at the planners' idle depth

Smooth timelapse no longer charges a prime volume it does not purge. A
tower printed with no tool change is exactly the idle depth: the
stability minimum for Type2, the wrapping detection depth for Type1.
Charging a full prime_volume on top made the previewed and arranged
tower deeper than the one that is printed.

The Type2 half of "a tool change reserves a tower whatever the purge
volumes resolve to" arrives with the base commit; here it only has to
survive the planner split, since Type1 already reserves per filament.

The wipe tower filament only joins the tool ordering when there is a
tower to join, which is the has_wipe_tower() half of the guard
Print::extruders applies.
This commit is contained in:
Hanif Koh
2026-09-09 15:45:16 +08:00
committed by HanifKoh
parent 869805132e
commit 2fdc16f9f2
3 changed files with 23 additions and 18 deletions
+3 -6
View File
@@ -96,12 +96,9 @@ WipeTowerFootprint estimate_wipe_tower_footprint(const ConfigBase &config, WipeT
// normalize_fdm_2 clearing enable_prime_tower. Its mixed-filament case is not modelled.
const bool need_wipe_tower = smooth_timelapse || wrapping;
// No tool change, nothing to purge; smooth timelapse still primes once.
size_t purge_count = 0;
if (filaments_cnt > 1)
purge_count = dual_nozzle ? filaments_cnt : filaments_cnt - 1;
else if (smooth_timelapse)
purge_count = 1;
// A tower printed for one of the reasons above has no tool change to purge for; both
// planners give it the idle depth below and nothing more.
const size_t purge_count = filaments_cnt > 1 ? (dual_nozzle ? filaments_cnt : filaments_cnt - 1) : 0;
// Type2 purges one volume per tool change. Type1 plans per filament below; here the volume
// only decides whether a tower exists.
+4 -2
View File
@@ -2341,10 +2341,12 @@ WipeTowerFootprint PartPlate::estimate_wipe_tower_footprint(const DynamicPrintCo
if (std::find(plate_extruders.begin(), plate_extruders.end(), id) == plate_extruders.end())
plate_extruders.push_back(id);
// The wipe tower filament joins the tool ordering even when unused (Print::extruders), so
// validation counts it.
// validation counts it - but only where there is a tower to join, which is the
// has_wipe_tower() half of that guard.
const ConfigOption *wipe_tower_filament_opt = config.option("wipe_tower_filament");
const ConfigOption *enable_prime_tower_opt = config.option("enable_prime_tower");
const int wipe_tower_filament = wipe_tower_filament_opt != nullptr ? wipe_tower_filament_opt->getInt() : 0;
if (plate_extruders.size() > 1 && wipe_tower_filament > 0 &&
if (enable_prime_tower_opt != nullptr && enable_prime_tower_opt->getBool() && plate_extruders.size() > 1 && wipe_tower_filament > 0 &&
std::find(plate_extruders.begin(), plate_extruders.end(), wipe_tower_filament) == plate_extruders.end())
plate_extruders.push_back(wipe_tower_filament);
if (plate_extruders.empty())