mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 19:01:02 +00:00
Size the Footprint Estimate from the Planners
The shared estimate reserved every tower with one volume-per-purge rule and the stability floor. Both planners do more: WipeTower (Type1) wipes each filament's own prime volume in whole lines, one block per adhesiveness category sized by its worst layer, rams the leaving filament at every nozzle change, and squares a rib tower from the planned depth; WipeTower2 (Type2) spaces its lines by wipe_tower_extra_spacing, not the Type1-only infill gap, and its extra flow cancels out of the depth. Both extend the ribs rather than the body below the stability minimum, size every layer including a thinner first one, and lay the brim in whole loops, WipeTower reporting half a spacing of line width on top. All of that now lives in estimate_wipe_tower_footprint, fed the planner (resolve_wipe_tower_type mirrors Print::wipe_tower_type and the CLI's Bambu Lab detection) and the filament ids rather than a count. Print passes its own tool set; the PartPlate adapter derives the plate's ids from the passed config and treats an explicit count as a floor, so the CLI's count-only callers size per filament too. The placement clamp also reserves a Type2 cone's base bulge, which the body box does not cover. The planner-mirroring helpers sit beside the planners in WipeTower and WipeTower2 so the two stay in sync; the libslic3r cases pin them to footprints measured from generated G-code.
This commit is contained in:
@@ -184,11 +184,13 @@ TEST_CASE("The wipe tower's toolchange planner flush follows the gcode flavor",
|
||||
}
|
||||
|
||||
// What Print feeds the shared estimate. The libslic3r WipeTowerEstimate cases cannot see this:
|
||||
// they call the estimator directly.
|
||||
static DynamicPrintConfig tower_estimate_config(const char *wall_type)
|
||||
// they call the estimator directly. The estimate counts the filaments the print really uses,
|
||||
// so the two-filament shape gives the outer wall the second one.
|
||||
static DynamicPrintConfig tower_estimate_config(const char *wall_type, unsigned int filaments = 2)
|
||||
{
|
||||
// 100 mm3 per purge on a 50 mm wide tower: one purge is 100/(layer_height * 50) of depth.
|
||||
return multifilament_config(2, {
|
||||
return multifilament_config(filaments, {
|
||||
{ "outer_wall_filament_id", filaments == 2 ? "2" : "1" },
|
||||
{ "enable_prime_tower", "1" },
|
||||
{ "wipe_tower_wall_type", wall_type },
|
||||
{ "prime_tower_width", "50" },
|
||||
@@ -277,7 +279,7 @@ TEST_CASE("A single-filament plate reserves a tower only when one is actually pr
|
||||
Model model;
|
||||
|
||||
SECTION("no tool change and nothing else that prints one") {
|
||||
const DynamicPrintConfig config = tower_estimate_config("rib");
|
||||
const DynamicPrintConfig config = tower_estimate_config("rib", 1);
|
||||
init_print({ cube(20) }, print, model, config);
|
||||
REQUIRE_FALSE(print.has_wipe_tower());
|
||||
CHECK_THAT(print.wipe_tower_data(1).depth, Catch::Matchers::WithinAbs(0., 1e-6));
|
||||
@@ -287,7 +289,7 @@ TEST_CASE("A single-filament plate reserves a tower only when one is actually pr
|
||||
// Print::apply runs normalize_fdm_2, which clears enable_prime_tower for a plate that
|
||||
// purges one filament and has neither smooth timelapse nor wrapping detection on.
|
||||
SECTION("a raft alone does not print one") {
|
||||
DynamicPrintConfig config = tower_estimate_config("rib");
|
||||
DynamicPrintConfig config = tower_estimate_config("rib", 1);
|
||||
config.set_deserialize_strict({ { "raft_layers", "3" } });
|
||||
init_print({ cube(20) }, print, model, config);
|
||||
REQUIRE_FALSE(print.config().enable_prime_tower.value);
|
||||
@@ -296,7 +298,7 @@ TEST_CASE("A single-filament plate reserves a tower only when one is actually pr
|
||||
}
|
||||
|
||||
SECTION("smooth timelapse prints one, and keeps enable_prime_tower on") {
|
||||
DynamicPrintConfig config = tower_estimate_config("rib");
|
||||
DynamicPrintConfig config = tower_estimate_config("rib", 1);
|
||||
config.set_deserialize_strict({ { "timelapse_type", "1" } });
|
||||
init_print({ cube(20) }, print, model, config);
|
||||
REQUIRE(print.has_wipe_tower());
|
||||
@@ -312,13 +314,12 @@ TEST_CASE("A tower printed without a tool change is still validated against the
|
||||
// checked against the bed.
|
||||
Print print;
|
||||
Model model;
|
||||
DynamicPrintConfig config = tower_estimate_config("rectangle");
|
||||
DynamicPrintConfig config = tower_estimate_config("rectangle", 1);
|
||||
// Relative E without a per-layer G92 is rejected before the tower is ever looked at, and
|
||||
// has_wipe_tower() wants a real exclusion polygon before it honours wrapping detection.
|
||||
config.set_deserialize_strict({ { "enable_wrapping_detection", "1" },
|
||||
{ "wrapping_exclude_area", "180x180,190x180,190x190,180x190" },
|
||||
{ "wipe_tower_x", "500" }, { "wipe_tower_y", "500" },
|
||||
{ "use_relative_e_distances", "0" } });
|
||||
{ "wipe_tower_x", "500" }, { "wipe_tower_y", "500" }, { "use_relative_e_distances", "0" } });
|
||||
|
||||
init_print({ cube(20) }, print, model, config);
|
||||
REQUIRE(print.extruders(true).size() == 1);
|
||||
|
||||
Reference in New Issue
Block a user