mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-25 02:47:46 +00:00
Reject a mixed filament as the wipe tower filament
This commit is contained in:
@@ -566,7 +566,7 @@ std::vector<unsigned int> Print::extruders(bool conside_custom_gcode) const
|
||||
|
||||
// If a wipe tower filament is explicitly set, ensure it participates in tool ordering.
|
||||
if (has_wipe_tower() && config().wipe_tower_filament != 0 && extruders.size() > 1) {
|
||||
assert(config().wipe_tower_filament > 0 && config().wipe_tower_filament < int(config().nozzle_diameter.size()));
|
||||
assert(config().wipe_tower_filament > 0 && config().wipe_tower_filament <= int(config().filament_diameter.size()));
|
||||
extruders.emplace_back(config().wipe_tower_filament - 1); // config value is 1-based
|
||||
}
|
||||
|
||||
@@ -1472,6 +1472,17 @@ StringObjectException Print::validate(std::vector<StringObjectException> *warnin
|
||||
}
|
||||
|
||||
if (this->has_wipe_tower() && ! m_objects.empty()) {
|
||||
// Orca: wipe_tower_filament (issue #10971) is inserted into the tool order after
|
||||
// resolve_mixed_filaments has expanded every mixed (virtual) slot, so a mixed slot here
|
||||
// would reach the G-code as a tool change to a slot no nozzle carries. The GUI hides
|
||||
// mixed slots from the option; this guards loaded projects and the CLI.
|
||||
if (m_config.wipe_tower_filament > 0) {
|
||||
const auto &is_mixed = m_config.filament_is_mixed.values;
|
||||
const size_t wipe_idx = size_t(m_config.wipe_tower_filament - 1);
|
||||
if (wipe_idx < is_mixed.size() && is_mixed[wipe_idx])
|
||||
return { L("The wipe tower filament cannot be a mixed filament."), nullptr, "wipe_tower_filament" };
|
||||
}
|
||||
|
||||
// Make sure all extruders use same diameter filament and have the same nozzle diameter
|
||||
// EPSILON comparison is used for nozzles and 10 % tolerance is used for filaments
|
||||
double first_nozzle_diam = m_config.nozzle_diameter.get_at(extruders.front());
|
||||
|
||||
@@ -211,3 +211,46 @@ TEST_CASE("By-object G-code lists a mixed slot's components in the filament head
|
||||
CHECK(gc.find("; filament: 1,2\n") != std::string::npos);
|
||||
CHECK(gc.find("; filament: 3") == std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE("Print::validate rejects a mixed filament as the wipe tower filament", "[MixedFilament]")
|
||||
{
|
||||
// The validate backstop refuses a mixed (virtual) slot as the wipe tower filament; the GUI hides
|
||||
// the slot from that option. Two cubes on physical filaments 1 and 2 make the tower real, and the
|
||||
// region roles mixed_config() points at the slot are reset so only the tower uses it.
|
||||
DynamicPrintConfig config = mixed_config(false);
|
||||
config.set_deserialize_strict({
|
||||
{"enable_prime_tower", "1"},
|
||||
{"wipe_tower_x", "50"}, // inside the 200x200 test bed
|
||||
{"wipe_tower_y", "50"}, // (the default y, 220, is not)
|
||||
{"layer_change_gcode", "G92 E0\n"}, // validate() relative-E reset, as in test_print.cpp's build_cubes
|
||||
{"outer_wall_filament_id", "0"},
|
||||
{"inner_wall_filament_id", "0"},
|
||||
{"sparse_infill_filament_id", "0"},
|
||||
{"internal_solid_filament_id", "0"},
|
||||
{"top_surface_filament_id", "0"},
|
||||
{"bottom_surface_filament_id", "0"},
|
||||
});
|
||||
const std::vector<std::vector<ConfigBase::SetDeserializeItem>> overrides{ { {"extruder", "1"} }, { {"extruder", "2"} } };
|
||||
|
||||
SECTION("a physical wipe tower filament validates") {
|
||||
config.set_deserialize_strict({{"wipe_tower_filament", "2"}});
|
||||
Print print;
|
||||
Model model;
|
||||
init_print(std::vector<TriangleMesh>{cube(20), cube(20)}, print, model, config, &overrides);
|
||||
REQUIRE(print.has_wipe_tower());
|
||||
const StringObjectException err = print.validate();
|
||||
INFO(err.string);
|
||||
CHECK(err.string.empty());
|
||||
}
|
||||
|
||||
SECTION("the mixed slot is refused") {
|
||||
config.set_deserialize_strict({{"wipe_tower_filament", "3"}});
|
||||
Print print;
|
||||
Model model;
|
||||
init_print(std::vector<TriangleMesh>{cube(20), cube(20)}, print, model, config, &overrides);
|
||||
REQUIRE(print.has_wipe_tower());
|
||||
const StringObjectException err = print.validate();
|
||||
CHECK_FALSE(err.string.empty());
|
||||
CHECK(err.opt_key == "wipe_tower_filament");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user