mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-26 11:27:41 +00:00
Fix flushing-volume warning for single-filament plates (#14704)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
This commit is contained in:
@@ -2397,6 +2397,55 @@ static void set_flush_volumes_matrix(std::vector<T> &out_matrix, const std::vect
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static bool has_zero_flush_volume_for_used_filaments(const std::vector<T> &fv_matrix,
|
||||
const std::vector<T> &flush_multipliers,
|
||||
const std::vector<int> &used_filaments)
|
||||
{
|
||||
if (used_filaments.size() < 2 || flush_multipliers.empty())
|
||||
return false;
|
||||
|
||||
if (fv_matrix.size() % flush_multipliers.size() != 0)
|
||||
return false;
|
||||
|
||||
const size_t matrix_len = fv_matrix.size() / flush_multipliers.size();
|
||||
const size_t row_len = size_t(std::sqrt(double(matrix_len)));
|
||||
if (row_len < 2 || row_len * row_len != matrix_len)
|
||||
return false;
|
||||
|
||||
std::vector<int> filtered_filaments;
|
||||
filtered_filaments.reserve(used_filaments.size());
|
||||
for (int filament_id : used_filaments) {
|
||||
if (filament_id <= 0 || filament_id > int(row_len))
|
||||
continue;
|
||||
if (std::find(filtered_filaments.begin(), filtered_filaments.end(), filament_id) == filtered_filaments.end())
|
||||
filtered_filaments.push_back(filament_id);
|
||||
}
|
||||
if (filtered_filaments.size() < 2)
|
||||
return false;
|
||||
|
||||
for (T multiplier : flush_multipliers) {
|
||||
if (multiplier == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
for (size_t nozzle_idx = 0; nozzle_idx < flush_multipliers.size(); nozzle_idx++) {
|
||||
const size_t block_offset = nozzle_idx * matrix_len;
|
||||
for (int from_id : filtered_filaments) {
|
||||
for (int to_id : filtered_filaments) {
|
||||
if (from_id == to_id)
|
||||
continue;
|
||||
|
||||
const size_t matrix_idx = block_offset + size_t(from_id - 1) * row_len + size_t(to_id - 1);
|
||||
if (matrix_idx < fv_matrix.size() && fv_matrix[matrix_idx] == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t get_extruder_index(const GCodeConfig& config, unsigned int filament_id);
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
@@ -10738,24 +10738,14 @@ bool GLCanvas3D::is_flushing_matrix_error() {
|
||||
if (!Sidebar::should_show_SEMM_buttons())
|
||||
return false;
|
||||
|
||||
std::vector<int> plate_extruders = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_extruders(true);
|
||||
if (plate_extruders.size() < 2)
|
||||
return false;
|
||||
|
||||
const auto &project_config = wxGetApp().preset_bundle->project_config;
|
||||
const std::vector<double> &config_matrix = (project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values;
|
||||
const std::vector<double> &config_multiplier = (project_config.option<ConfigOptionFloats>("flush_multiplier"))->values;
|
||||
|
||||
for (auto multiplier : config_multiplier) {
|
||||
if (multiplier == 0) return true;
|
||||
}
|
||||
|
||||
int matrix_len = config_matrix.size() / config_multiplier.size();
|
||||
int row_len = std::sqrt(matrix_len);
|
||||
for (int i = 0; i < config_matrix.size(); i++)
|
||||
{
|
||||
int relative_id = i % matrix_len;
|
||||
int row_id = relative_id / row_len;
|
||||
int col_id = relative_id % row_len;
|
||||
if (row_id != col_id && config_matrix[i] == 0) return true;
|
||||
}
|
||||
return false;
|
||||
return has_zero_flush_volume_for_used_filaments(config_matrix, config_multiplier, plate_extruders);
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_is_any_volume_outside() const
|
||||
|
||||
@@ -235,6 +235,56 @@ SCENARIO("Config ini load/save interface", "[Config]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Flush-volume warning predicate respects used filament transitions", "[Config][Regression]")
|
||||
{
|
||||
const std::vector<double> multipliers = {1.0};
|
||||
|
||||
SECTION("Single used filament does not trigger warning with zero transition entries")
|
||||
{
|
||||
const std::vector<double> matrix = {
|
||||
0.0, 0.0,
|
||||
0.0, 0.0
|
||||
};
|
||||
const std::vector<int> used_filaments = {1};
|
||||
|
||||
REQUIRE_FALSE(has_zero_flush_volume_for_used_filaments(matrix, multipliers, used_filaments));
|
||||
}
|
||||
|
||||
SECTION("Two used filaments trigger warning when transition flush entry is zero")
|
||||
{
|
||||
const std::vector<double> matrix = {
|
||||
0.0, 0.0,
|
||||
0.0, 0.0
|
||||
};
|
||||
const std::vector<int> used_filaments = {1, 2};
|
||||
|
||||
REQUIRE(has_zero_flush_volume_for_used_filaments(matrix, multipliers, used_filaments));
|
||||
}
|
||||
|
||||
SECTION("Two used filaments do not trigger warning when transitions are non-zero")
|
||||
{
|
||||
const std::vector<double> matrix = {
|
||||
0.0, 280.0,
|
||||
280.0, 0.0
|
||||
};
|
||||
const std::vector<int> used_filaments = {1, 2};
|
||||
|
||||
REQUIRE_FALSE(has_zero_flush_volume_for_used_filaments(matrix, multipliers, used_filaments));
|
||||
}
|
||||
|
||||
SECTION("Zero multiplier still triggers warning when multiple filaments are used")
|
||||
{
|
||||
const std::vector<double> matrix = {
|
||||
0.0, 280.0,
|
||||
280.0, 0.0
|
||||
};
|
||||
const std::vector<double> zero_multiplier = {0.0};
|
||||
const std::vector<int> used_filaments = {1, 2};
|
||||
|
||||
REQUIRE(has_zero_flush_volume_for_used_filaments(matrix, zero_multiplier, used_filaments));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: https://github.com/SoftFever/OrcaSlicer/issues/11269 - Is this test still relevant? Delete if not.
|
||||
// It was failing so at least "nozzle_type" and "extruder_printable_area" could not be serialized
|
||||
// and an exception was thrown, but "nozzle_type" has been around for at least 3 months now.
|
||||
|
||||
Reference in New Issue
Block a user