ENH: flush_volume support multi_extruder and fix bug
Change-Id: Id6b041f71ee6e55e68a6937f24ce791caac8e708
This commit is contained in:
parent
8b2544df41
commit
6fbad9ed33
|
@ -3142,14 +3142,8 @@ int CLI::run(int argc, char **argv)
|
|||
|
||||
//computing
|
||||
ConfigOptionBools* filament_is_support = m_print_config.option<ConfigOptionBools>("filament_is_support", true);
|
||||
std::vector<double>& flush_vol_matrix = m_print_config.option<ConfigOptionFloats>("flush_volumes_matrix", true)->values;
|
||||
//std::vector<float>& flush_vol_vector = m_print_config.option<ConfigOptionFloats>("flush_volumes_vector", true)->values;
|
||||
flush_vol_matrix.resize(project_filament_count*project_filament_count, 0.f);
|
||||
//flush_vol_vector.resize(project_filament_count);
|
||||
//set multiplier to 1?
|
||||
m_print_config.option<ConfigOptionFloat>("flush_multiplier", true)->set(new ConfigOptionFloat(1.f));
|
||||
|
||||
const std::vector<int>& min_flush_volumes = Slic3r::GUI::get_min_flush_volumes(m_print_config);
|
||||
const std::vector<int> &min_flush_volumes = Slic3r::GUI::get_min_flush_volumes(m_print_config, 0);
|
||||
|
||||
if (filament_is_support->size() != project_filament_count)
|
||||
{
|
||||
|
@ -3165,40 +3159,50 @@ int CLI::run(int argc, char **argv)
|
|||
BOOST_LOG_TRIVIAL(info) << boost::format("filament_is_support: %1%") % filament_is_support->serialize();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("flush_volumes_matrix before computing: %1%") % m_print_config.option<ConfigOptionFloats>("flush_volumes_matrix")->serialize();
|
||||
}
|
||||
for (int from_idx = 0; from_idx < project_filament_count; from_idx++) {
|
||||
const std::string& from_color = project_filament_colors[from_idx];
|
||||
unsigned char from_rgb[4] = {};
|
||||
Slic3r::GUI::BitmapCache::parse_color4(from_color, from_rgb);
|
||||
bool is_from_support = filament_is_support->get_at(from_idx);
|
||||
for (int to_idx = 0; to_idx < project_filament_count; to_idx++) {
|
||||
bool is_to_support = filament_is_support->get_at(to_idx);
|
||||
if (from_idx == to_idx) {
|
||||
flush_vol_matrix[project_filament_count*from_idx + to_idx] = 0.f;
|
||||
}
|
||||
else {
|
||||
int flushing_volume = 0;
|
||||
if (is_to_support) {
|
||||
flushing_volume = Slic3r::g_flush_volume_to_support;
|
||||
}
|
||||
else {
|
||||
const std::string& to_color = project_filament_colors[to_idx];
|
||||
unsigned char to_rgb[4] = {};
|
||||
Slic3r::GUI::BitmapCache::parse_color4(to_color, to_rgb);
|
||||
//BOOST_LOG_TRIVIAL(info) << boost::format("src_idx %1%, src color %2%, dst idex %3%, dst color %4%")%from_idx %from_color %to_idx %to_color;
|
||||
//BOOST_LOG_TRIVIAL(info) << boost::format("src_rgba {%1%,%2%,%3%,%4%} dst_rgba {%5%,%6%,%7%,%8%}")%(unsigned int)(from_rgb[0]) %(unsigned int)(from_rgb[1]) %(unsigned int)(from_rgb[2]) %(unsigned int)(from_rgb[3])
|
||||
// %(unsigned int)(to_rgb[0]) %(unsigned int)(to_rgb[1]) %(unsigned int)(to_rgb[2]) %(unsigned int)(to_rgb[3]);
|
||||
|
||||
Slic3r::FlushVolCalculator calculator(min_flush_volumes[from_idx], Slic3r::g_max_flush_volume);
|
||||
size_t nozzle_nums = 1;
|
||||
auto opt_nozzle_diameters = m_print_config.option<ConfigOptionFloats>("nozzle_diameter");
|
||||
if (opt_nozzle_diameters != nullptr) {
|
||||
nozzle_nums = opt_nozzle_diameters->values.size();
|
||||
}
|
||||
|
||||
flushing_volume = calculator.calc_flush_vol(from_rgb[3], from_rgb[0], from_rgb[1], from_rgb[2], to_rgb[3], to_rgb[0], to_rgb[1], to_rgb[2]);
|
||||
if (is_from_support) {
|
||||
flushing_volume = std::max(Slic3r::g_min_flush_volume_from_support, flushing_volume);
|
||||
std::vector<double> &flush_vol_matrix = m_print_config.option<ConfigOptionFloats>("flush_volumes_matrix", true)->values;
|
||||
flush_vol_matrix.resize(project_filament_count * project_filament_count * nozzle_nums, 0.f);
|
||||
|
||||
// set multiplier to 1?
|
||||
std::vector<double>& flush_multipliers = m_print_config.option<ConfigOptionFloats>("flush_multiplier", true)->values;
|
||||
flush_multipliers.resize(nozzle_nums, 1.f);
|
||||
|
||||
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) {
|
||||
std::vector<double> flush_vol_mtx = get_flush_volumes_matrix(flush_vol_matrix, nozzle_id, nozzle_nums);
|
||||
for (int from_idx = 0; from_idx < project_filament_count; from_idx++) {
|
||||
const std::string &from_color = project_filament_colors[from_idx];
|
||||
unsigned char from_rgb[4] = {};
|
||||
Slic3r::GUI::BitmapCache::parse_color4(from_color, from_rgb);
|
||||
bool is_from_support = filament_is_support->get_at(from_idx);
|
||||
for (int to_idx = 0; to_idx < project_filament_count; to_idx++) {
|
||||
bool is_to_support = filament_is_support->get_at(to_idx);
|
||||
if (from_idx == to_idx) {
|
||||
flush_vol_mtx[project_filament_count * from_idx + to_idx] = 0.f;
|
||||
} else {
|
||||
int flushing_volume = 0;
|
||||
if (is_to_support) {
|
||||
flushing_volume = Slic3r::g_flush_volume_to_support;
|
||||
} else {
|
||||
const std::string &to_color = project_filament_colors[to_idx];
|
||||
unsigned char to_rgb[4] = {};
|
||||
Slic3r::GUI::BitmapCache::parse_color4(to_color, to_rgb);
|
||||
|
||||
Slic3r::FlushVolCalculator calculator(min_flush_volumes[from_idx], Slic3r::g_max_flush_volume);
|
||||
|
||||
flushing_volume = calculator.calc_flush_vol(from_rgb[3], from_rgb[0], from_rgb[1], from_rgb[2], to_rgb[3], to_rgb[0], to_rgb[1], to_rgb[2]);
|
||||
if (is_from_support) { flushing_volume = std::max(Slic3r::g_min_flush_volume_from_support, flushing_volume); }
|
||||
}
|
||||
}
|
||||
|
||||
flush_vol_matrix[project_filament_count * from_idx + to_idx] = flushing_volume;
|
||||
//flushing_volume = int(flushing_volume * get_flush_multiplier());
|
||||
flush_vol_mtx[project_filament_count * from_idx + to_idx] = flushing_volume;
|
||||
}
|
||||
}
|
||||
set_flush_volumes_matrix(flush_vol_matrix, flush_vol_mtx, nozzle_id, nozzle_nums);
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("flush_volumes_matrix after computed: %1%")%m_print_config.option<ConfigOptionFloats>("flush_volumes_matrix")->serialize();
|
||||
|
|
|
@ -3195,7 +3195,7 @@ GCode::LayerResult GCode::process_layer(
|
|||
|
||||
// BBS: get next extruder according to flush and soluble
|
||||
auto get_next_extruder = [&](int current_extruder,const std::vector<unsigned int>&extruders) {
|
||||
std::vector<float> flush_matrix(cast<float>(m_config.flush_volumes_matrix.values));
|
||||
std::vector<float> flush_matrix(cast<float>(get_flush_volumes_matrix(m_config.flush_volumes_matrix.values, 0, m_config.nozzle_diameter.values.size())));
|
||||
const unsigned int number_of_extruders = (unsigned int)(sqrt(flush_matrix.size()) + EPSILON);
|
||||
// Extract purging volumes for each extruder pair:
|
||||
std::vector<std::vector<float>> wipe_volumes;
|
||||
|
@ -5370,8 +5370,8 @@ std::string GCode::set_extruder(unsigned int filament_id, double print_z, bool b
|
|||
//BBS: add handling for filament change in start gcode
|
||||
int previous_filament_id = -1;
|
||||
if (m_writer.extruder() != nullptr || m_start_gcode_filament != -1) {
|
||||
std::vector<float> flush_matrix(cast<float>(m_config.flush_volumes_matrix.values));
|
||||
const unsigned int number_of_extruders = (unsigned int)(sqrt(flush_matrix.size()) + EPSILON);
|
||||
std::vector<float> flush_matrix(cast<float>(get_flush_volumes_matrix(m_config.flush_volumes_matrix.values, 0, m_config.nozzle_diameter.values.size())));
|
||||
const unsigned int number_of_extruders = (unsigned int) (m_config.filament_colour.values.size()); // if is multi_extruder only use the fist extruder matrix
|
||||
if (m_writer.extruder() != nullptr)
|
||||
assert(m_writer.extruder()->id() < number_of_extruders);
|
||||
else
|
||||
|
@ -5384,7 +5384,7 @@ std::string GCode::set_extruder(unsigned int filament_id, double print_z, bool b
|
|||
old_retract_length_toolchange = m_config.retract_length_toolchange.get_at(previous_extruder_id);
|
||||
old_filament_temp = this->on_first_layer()? m_config.nozzle_temperature_initial_layer.get_at(previous_filament_id) : m_config.nozzle_temperature.get_at(previous_filament_id);
|
||||
wipe_volume = flush_matrix[previous_filament_id * number_of_extruders + filament_id];
|
||||
wipe_volume *= m_config.flush_multiplier;
|
||||
wipe_volume *= m_config.flush_multiplier.get_at(0); // if is multi_extruder only use the fist extruder matrix
|
||||
old_filament_e_feedrate = (int) (60.0 * m_config.filament_max_volumetric_speed.get_at(previous_filament_id) / filament_area);
|
||||
old_filament_e_feedrate = old_filament_e_feedrate == 0 ? 100 : old_filament_e_feedrate;
|
||||
//BBS: must clean m_start_gcode_filament
|
||||
|
|
|
@ -829,6 +829,12 @@ void ToolOrdering::collect_extruder_statistics(bool prime_multi_material)
|
|||
|
||||
void ToolOrdering::reorder_extruders_for_minimum_flush_volume()
|
||||
{
|
||||
bool is_multi_extruder = false;
|
||||
if (is_multi_extruder) {
|
||||
reorder_extruders_for_minimum_flush_volume_multi_extruder();
|
||||
return;
|
||||
}
|
||||
|
||||
const PrintConfig *print_config = m_print_config_ptr;
|
||||
if (!print_config && m_print_object_ptr) {
|
||||
print_config = &(m_print_object_ptr->print()->config());
|
||||
|
@ -922,6 +928,132 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume()
|
|||
}
|
||||
}
|
||||
|
||||
void ToolOrdering::reorder_extruders_for_minimum_flush_volume_multi_extruder()
|
||||
{
|
||||
const PrintConfig *print_config = m_print_config_ptr;
|
||||
if (!print_config && m_print_object_ptr) {
|
||||
print_config = &(m_print_object_ptr->print()->config());
|
||||
}
|
||||
|
||||
if (!print_config || m_layer_tools.empty())
|
||||
return;
|
||||
|
||||
const unsigned int number_of_extruders = (unsigned int) (print_config->filament_colour.values.size() + EPSILON);
|
||||
// todo multi_extruders: get filament_maps
|
||||
std::vector<int> filament_maps;
|
||||
for (int i = 0; i <= number_of_extruders / 2; ++i) {
|
||||
filament_maps.push_back(1);
|
||||
}
|
||||
for (int i = number_of_extruders / 2 + 1; i < number_of_extruders; ++i) {
|
||||
filament_maps.push_back(2);
|
||||
}
|
||||
|
||||
using FlushMatrix = std::vector<std::vector<float>>;
|
||||
size_t nozzle_nums = print_config->nozzle_diameter.values.size();
|
||||
std::vector<FlushMatrix> nozzle_flush_mtx;
|
||||
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) {
|
||||
std::vector<float> flush_matrix(cast<float>(get_flush_volumes_matrix(print_config->flush_volumes_matrix.values, nozzle_id, nozzle_nums)));
|
||||
std::vector<std::vector<float>> wipe_volumes;
|
||||
for (unsigned int i = 0; i < number_of_extruders; ++i)
|
||||
wipe_volumes.push_back(std::vector<float>(flush_matrix.begin() + i * number_of_extruders, flush_matrix.begin() + (i + 1) * number_of_extruders));
|
||||
|
||||
nozzle_flush_mtx.emplace_back(wipe_volumes);
|
||||
}
|
||||
|
||||
auto extruders_to_hash_key = [](const std::vector<unsigned int> &extruders, std::optional<unsigned int> initial_extruder_id) -> uint32_t {
|
||||
uint32_t hash_key = 0;
|
||||
// high 16 bit define initial extruder ,low 16 bit define extruder set
|
||||
if (initial_extruder_id) hash_key |= (1 << (16 + *initial_extruder_id));
|
||||
for (auto item : extruders) hash_key |= (1 << item);
|
||||
return hash_key;
|
||||
};
|
||||
|
||||
std::vector<LayerPrintSequence> other_layers_seqs;
|
||||
const ConfigOptionInts * other_layers_print_sequence_op = print_config->option<ConfigOptionInts>("other_layers_print_sequence");
|
||||
const ConfigOptionInt * other_layers_print_sequence_nums_op = print_config->option<ConfigOptionInt>("other_layers_print_sequence_nums");
|
||||
if (other_layers_print_sequence_op && other_layers_print_sequence_nums_op) {
|
||||
const std::vector<int> &print_sequence = other_layers_print_sequence_op->values;
|
||||
int sequence_nums = other_layers_print_sequence_nums_op->value;
|
||||
other_layers_seqs = get_other_layers_print_sequence(sequence_nums, print_sequence);
|
||||
}
|
||||
|
||||
// other_layers_seq: the layer_idx and extruder_idx are base on 1
|
||||
auto get_custom_seq = [&other_layers_seqs](int layer_idx, std::vector<int> &out_seq) -> bool {
|
||||
for (size_t idx = other_layers_seqs.size() - 1; idx != size_t(-1); --idx) {
|
||||
const auto &other_layers_seq = other_layers_seqs[idx];
|
||||
if (layer_idx + 1 >= other_layers_seq.first.first && layer_idx + 1 <= other_layers_seq.first.second) {
|
||||
out_seq = other_layers_seq.second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::optional<unsigned int> current_extruder_id;
|
||||
|
||||
std::vector<std::optional<unsigned int>> nozzle_to_cur_filaments;
|
||||
|
||||
for (int i = 0; i < m_layer_tools.size(); ++i) {
|
||||
LayerTools < = m_layer_tools[i];
|
||||
if (lt.extruders.empty())
|
||||
continue;
|
||||
|
||||
std::vector<int> custom_extruder_seq;
|
||||
if (get_custom_seq(i, custom_extruder_seq) && !custom_extruder_seq.empty()) {
|
||||
std::vector<unsigned int> unsign_custom_extruder_seq;
|
||||
for (int extruder : custom_extruder_seq) {
|
||||
unsigned int unsign_extruder = static_cast<unsigned int>(extruder) - 1;
|
||||
auto it = std::find(lt.extruders.begin(), lt.extruders.end(), unsign_extruder);
|
||||
if (it != lt.extruders.end()) {
|
||||
unsign_custom_extruder_seq.emplace_back(unsign_extruder);
|
||||
nozzle_to_cur_filaments[filament_maps[unsign_extruder]] = unsign_extruder;
|
||||
}
|
||||
}
|
||||
assert(lt.extruders.size() == unsign_custom_extruder_seq.size());
|
||||
lt.extruders = unsign_custom_extruder_seq;
|
||||
current_extruder_id = lt.extruders.back();
|
||||
continue;
|
||||
}
|
||||
|
||||
// The algorithm complexity is O(n2*2^n)
|
||||
if (i != 0) {
|
||||
std::vector<std::vector<unsigned int>> nozzle_filaments;
|
||||
nozzle_filaments.resize(nozzle_nums);
|
||||
|
||||
for (unsigned int filament_id : lt.extruders) {
|
||||
nozzle_filaments[filament_maps[filament_id] - 1].emplace_back(filament_id);
|
||||
}
|
||||
|
||||
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id)
|
||||
{
|
||||
auto hash_key = extruders_to_hash_key(nozzle_filaments[nozzle_id], nozzle_to_cur_filaments[nozzle_id]);
|
||||
auto iter = m_tool_order_cache.find(hash_key);
|
||||
if (iter == m_tool_order_cache.end()) {
|
||||
nozzle_filaments[nozzle_id] = get_extruders_order(nozzle_flush_mtx[nozzle_id], nozzle_filaments[nozzle_id], nozzle_to_cur_filaments[nozzle_id]);
|
||||
std::vector<uint8_t> hash_val;
|
||||
hash_val.reserve(nozzle_filaments[nozzle_id].size());
|
||||
for (auto item : nozzle_filaments[nozzle_id])
|
||||
hash_val.emplace_back(static_cast<uint8_t>(item));
|
||||
m_tool_order_cache[hash_key] = hash_val;
|
||||
} else {
|
||||
std::vector<unsigned int> extruder_order;
|
||||
extruder_order.reserve(iter->second.size());
|
||||
for (auto item : iter->second)
|
||||
extruder_order.emplace_back(static_cast<unsigned int>(item));
|
||||
nozzle_filaments[nozzle_id] = std::move(extruder_order);
|
||||
}
|
||||
nozzle_to_cur_filaments[nozzle_id] = nozzle_filaments[nozzle_id].back();
|
||||
}
|
||||
|
||||
lt.extruders.clear();
|
||||
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) {
|
||||
lt.extruders.insert(lt.extruders.end(), nozzle_filaments[nozzle_id].begin(), nozzle_filaments[nozzle_id].end());
|
||||
}
|
||||
}
|
||||
current_extruder_id = lt.extruders.back();
|
||||
}
|
||||
}
|
||||
|
||||
// Layers are marked for infinite skirt aka draft shield. Not all the layers have to be printed.
|
||||
void ToolOrdering::mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height)
|
||||
{
|
||||
|
|
|
@ -197,6 +197,7 @@ private:
|
|||
void mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height);
|
||||
void collect_extruder_statistics(bool prime_multi_material);
|
||||
void reorder_extruders_for_minimum_flush_volume();
|
||||
void reorder_extruders_for_minimum_flush_volume_multi_extruder();
|
||||
|
||||
// BBS
|
||||
std::vector<unsigned int> generate_first_layer_tool_order(const Print& print);
|
||||
|
|
|
@ -831,14 +831,14 @@ namespace client
|
|||
// Not a percent, just return the value.
|
||||
output.set_d(opt_floats->get_at(index).value);
|
||||
} else {
|
||||
// Resolve dependencies using the "ratio_over" link to a parent value.
|
||||
const ConfigOptionDef *opt_def = print_config_def.get(opt_key);
|
||||
assert(opt_def != nullptr);
|
||||
assert(opt_def->type() == coFloatsOrPercents);
|
||||
|
||||
FloatOrPercent opt_value = opt_floats->get_at(index);
|
||||
double v = opt_value.value;
|
||||
if (opt_value.percent) {
|
||||
// Resolve dependencies using the "ratio_over" link to a parent value.
|
||||
const ConfigOptionDef *opt_def = print_config_def.get(opt_key);
|
||||
assert(opt_def != nullptr);
|
||||
assert(opt_def->type == coFloatsOrPercents);
|
||||
v *= 0.01;
|
||||
while (true) {
|
||||
const ConfigOption *opt_parent = opt_def->ratio_over.empty() ? nullptr : ctx->resolve_symbol(opt_def->ratio_over);
|
||||
|
|
|
@ -1627,9 +1627,9 @@ void PresetBundle::load_selections(AppConfig &config, const PresetPreferences& p
|
|||
project_config.option<ConfigOptionFloats>("flush_volumes_vector")->values = std::vector<double>(flush_volumes_vector.begin(), flush_volumes_vector.end());
|
||||
}
|
||||
if (config.has("app", "flush_multiplier")) {
|
||||
std::string str_flush_multiplier = config.get("app", "flush_multiplier");
|
||||
if (!str_flush_multiplier.empty())
|
||||
project_config.option<ConfigOptionFloat>("flush_multiplier")->set(new ConfigOptionFloat(std::stof(str_flush_multiplier)));
|
||||
boost::algorithm::split(matrix, config.get("app", "flush_multiplier"), boost::algorithm::is_any_of("|"));
|
||||
auto flush_multipliers = matrix | boost::adaptors::transformed(boost::lexical_cast<double, std::string>);
|
||||
project_config.option<ConfigOptionFloats>("flush_multiplier")->values = std::vector<double>(flush_multipliers.begin(), flush_multipliers.end());
|
||||
}
|
||||
|
||||
// Update visibility of presets based on their compatibility with the active printer.
|
||||
|
@ -1706,8 +1706,11 @@ void PresetBundle::export_selections(AppConfig &config)
|
|||
|
||||
config.set("presets", PRESET_PRINTER_NAME, printers.get_selected_preset_name());
|
||||
|
||||
auto flush_multi_opt = project_config.option<ConfigOptionFloat>("flush_multiplier");
|
||||
config.set("flush_multiplier", std::to_string(flush_multi_opt ? flush_multi_opt->getFloat() : 1.0f));
|
||||
std::string flush_multiplier_str = boost::algorithm::join(project_config.option<ConfigOptionFloats>("flush_multiplier")->values |
|
||||
boost::adaptors::transformed(static_cast<std::string (*)(double)>(std::to_string)),
|
||||
"|");
|
||||
config.set("flush_multiplier", flush_multiplier_str);
|
||||
|
||||
// BBS
|
||||
//config.set("presets", "sla_print", sla_prints.get_selected_preset_name());
|
||||
//config.set("presets", "sla_material", sla_materials.get_selected_preset_name());
|
||||
|
@ -3631,7 +3634,9 @@ void PresetBundle::update_multi_material_filament_presets()
|
|||
|
||||
// Now verify if flush_volumes_matrix has proper size (it is used to deduce number of extruders in wipe tower generator):
|
||||
std::vector<double> old_matrix = this->project_config.option<ConfigOptionFloats>("flush_volumes_matrix")->values;
|
||||
size_t old_number_of_filaments = size_t(sqrt(old_matrix.size())+EPSILON);
|
||||
|
||||
size_t nozzle_nums = full_config().option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
size_t old_number_of_filaments = size_t(sqrt(old_matrix.size() / nozzle_nums) + EPSILON);
|
||||
if (num_filaments != old_number_of_filaments) {
|
||||
// First verify if purging volumes presets for each extruder matches number of extruders
|
||||
std::vector<double>& filaments = this->project_config.option<ConfigOptionFloats>("flush_volumes_vector")->values;
|
||||
|
@ -3644,16 +3649,38 @@ void PresetBundle::update_multi_material_filament_presets()
|
|||
filaments.pop_back();
|
||||
}
|
||||
|
||||
std::vector<double> new_matrix;
|
||||
for (unsigned int i=0;i< num_filaments;++i)
|
||||
for (unsigned int j=0;j< num_filaments;++j) {
|
||||
// append the value for this pair from the old matrix (if it's there):
|
||||
if (i < old_number_of_filaments && j < old_number_of_filaments)
|
||||
new_matrix.push_back(old_matrix[i* old_number_of_filaments + j]);
|
||||
else
|
||||
new_matrix.push_back( i == j ? 0. : filaments[2 * i] + filaments[2 * j + 1]); // so it matches new extruder volumes
|
||||
}
|
||||
this->project_config.option<ConfigOptionFloats>("flush_volumes_matrix")->values = new_matrix;
|
||||
if (nozzle_nums > 1) {
|
||||
size_t old_matrix_size = old_number_of_filaments * old_number_of_filaments;
|
||||
size_t new_matrix_size = num_filaments * num_filaments;
|
||||
std::vector<double> new_matrix(new_matrix_size * nozzle_nums, 0);
|
||||
for (unsigned int i = 0; i < num_filaments; ++i)
|
||||
for (unsigned int j = 0; j < num_filaments; ++j) {
|
||||
if (i < old_number_of_filaments && j < old_number_of_filaments) {
|
||||
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) {
|
||||
new_matrix[i * num_filaments + j + new_matrix_size * nozzle_id] = old_matrix[i * old_number_of_filaments + j + old_matrix_size * nozzle_id];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) {
|
||||
new_matrix[i * num_filaments + j + new_matrix_size * nozzle_id] = (i == j ? 0. : filaments[2 * i] + filaments[2 * j + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
this->project_config.option<ConfigOptionFloats>("flush_volumes_matrix")->values = new_matrix;
|
||||
}
|
||||
else {
|
||||
std::vector<double> new_matrix;
|
||||
for (unsigned int i = 0; i < num_filaments; ++i)
|
||||
for (unsigned int j = 0; j < num_filaments; ++j) {
|
||||
// append the value for this pair from the old matrix (if it's there):
|
||||
if (i < old_number_of_filaments && j < old_number_of_filaments)
|
||||
new_matrix.push_back(old_matrix[i * old_number_of_filaments + j]);
|
||||
else
|
||||
new_matrix.push_back(i == j ? 0. : filaments[2 * i] + filaments[2 * j + 1]); // so it matches new extruder volumes
|
||||
}
|
||||
this->project_config.option<ConfigOptionFloats>("flush_volumes_matrix")->values = new_matrix;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2346,15 +2346,8 @@ void Print::_make_wipe_tower()
|
|||
{
|
||||
m_wipe_tower_data.clear();
|
||||
|
||||
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
|
||||
std::vector<float> flush_matrix(cast<float>(m_config.flush_volumes_matrix.values));
|
||||
|
||||
// BBS
|
||||
const unsigned int number_of_extruders = (unsigned int)(sqrt(flush_matrix.size()) + EPSILON);
|
||||
// Extract purging volumes for each extruder pair:
|
||||
std::vector<std::vector<float>> wipe_volumes;
|
||||
for (unsigned int i = 0; i<number_of_extruders; ++i)
|
||||
wipe_volumes.push_back(std::vector<float>(flush_matrix.begin()+i*number_of_extruders, flush_matrix.begin()+(i+1)*number_of_extruders));
|
||||
const unsigned int number_of_extruders = (unsigned int)(m_config.filament_colour.values.size());
|
||||
|
||||
// Let the ToolOrdering class know there will be initial priming extrusions at the start of the print.
|
||||
// BBS: priming logic is removed, so don't consider it in tool ordering
|
||||
|
@ -2406,9 +2399,6 @@ void Print::_make_wipe_tower()
|
|||
WipeTower wipe_tower(m_config, m_plate_index, m_origin, m_config.prime_volume, m_wipe_tower_data.tool_ordering.first_extruder(),
|
||||
m_wipe_tower_data.tool_ordering.empty() ? 0.f : m_wipe_tower_data.tool_ordering.back().print_z);
|
||||
|
||||
//wipe_tower.set_retract();
|
||||
//wipe_tower.set_zhop();
|
||||
|
||||
// Set the extruder & material properties at the wipe tower object.
|
||||
for (size_t i = 0; i < number_of_extruders; ++ i)
|
||||
wipe_tower.set_extruder(i, m_config);
|
||||
|
@ -2420,45 +2410,119 @@ void Print::_make_wipe_tower()
|
|||
// Lets go through the wipe tower layers and determine pairs of extruder changes for each
|
||||
// to pass to wipe_tower (so that it can use it for planning the layout of the tower)
|
||||
{
|
||||
// BBS: priming logic is removed, so get the initial extruder by first_extruder()
|
||||
unsigned int current_extruder_id = m_wipe_tower_data.tool_ordering.first_extruder();
|
||||
for (auto &layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers
|
||||
if (!layer_tools.has_wipe_tower) continue;
|
||||
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
|
||||
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id);
|
||||
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
|
||||
bool is_mutli_extruder = m_config.nozzle_diameter.values.size() > 1;
|
||||
size_t nozzle_nums = m_config.nozzle_diameter.values.size();
|
||||
if (is_mutli_extruder) {
|
||||
using FlushMatrix = std::vector<std::vector<float>>;
|
||||
std::vector<FlushMatrix> multi_extruder_flush;
|
||||
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) {
|
||||
std::vector<float> flush_matrix(cast<float>(get_flush_volumes_matrix(m_config.flush_volumes_matrix.values, nozzle_id, nozzle_nums)));
|
||||
std::vector<std::vector<float>> wipe_volumes;
|
||||
for (unsigned int i = 0; i < number_of_extruders; ++i)
|
||||
wipe_volumes.push_back(std::vector<float>(flush_matrix.begin() + i * number_of_extruders, flush_matrix.begin() + (i + 1) * number_of_extruders));
|
||||
|
||||
for (const auto extruder_id : layer_tools.extruders) {
|
||||
// BBS: priming logic is removed, so no need to do toolchange for first extruder
|
||||
if (/*(first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || */extruder_id != current_extruder_id) {
|
||||
float volume_to_purge = wipe_volumes[current_extruder_id][extruder_id];
|
||||
volume_to_purge *= m_config.flush_multiplier;
|
||||
multi_extruder_flush.emplace_back(wipe_volumes);
|
||||
}
|
||||
|
||||
// Not all of that can be used for infill purging:
|
||||
//volume_to_purge -= (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
||||
// todo multi_extruders: get filament_maps
|
||||
std::vector<int> filament_maps;
|
||||
for (int i = 0; i <= number_of_extruders / 2; ++i) {
|
||||
filament_maps.push_back(1);
|
||||
}
|
||||
for (int i = number_of_extruders / 2 + 1; i < number_of_extruders; ++i) {
|
||||
filament_maps.push_back(2);
|
||||
}
|
||||
|
||||
// try to assign some infills/objects for the wiping:
|
||||
volume_to_purge = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_extruder_id, extruder_id, volume_to_purge);
|
||||
std::vector<unsigned int> nozzle_cur_filament_ids(nozzle_nums, -1);
|
||||
unsigned int current_filament_id = m_wipe_tower_data.tool_ordering.first_extruder();
|
||||
size_t cur_nozzle_id = filament_maps[current_filament_id] - 1;
|
||||
nozzle_cur_filament_ids[cur_nozzle_id] = current_filament_id;
|
||||
|
||||
// add back the minimal amount toforce on the wipe tower:
|
||||
//volume_to_purge += (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
||||
for (auto &layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers
|
||||
if (!layer_tools.has_wipe_tower) continue;
|
||||
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
|
||||
wipe_tower.plan_toolchange((float) layer_tools.print_z, (float) layer_tools.wipe_tower_layer_height, current_filament_id, current_filament_id);
|
||||
|
||||
// request a toolchange at the wipe tower with at least volume_to_wipe purging amount
|
||||
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height,
|
||||
current_extruder_id, extruder_id, m_config.prime_volume, volume_to_purge);
|
||||
current_extruder_id = extruder_id;
|
||||
for (const auto filament_id : layer_tools.extruders) {
|
||||
if (filament_id == current_filament_id)
|
||||
continue;
|
||||
|
||||
int nozzle_id = filament_maps[filament_id] - 1;
|
||||
unsigned int pre_filament_id = nozzle_cur_filament_ids[nozzle_id];
|
||||
if (pre_filament_id == filament_id)
|
||||
continue;
|
||||
|
||||
float volume_to_purge = multi_extruder_flush[nozzle_id][pre_filament_id][filament_id];
|
||||
volume_to_purge *= m_config.flush_multiplier.get_at(nozzle_id);
|
||||
volume_to_purge = pre_filament_id == -1 ? 0 :
|
||||
layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_filament_id, filament_id, volume_to_purge);
|
||||
wipe_tower.plan_toolchange((float) layer_tools.print_z, (float) layer_tools.wipe_tower_layer_height, current_filament_id, filament_id,
|
||||
m_config.prime_volume, volume_to_purge);
|
||||
current_filament_id = filament_id;
|
||||
nozzle_cur_filament_ids[nozzle_id] = filament_id;
|
||||
}
|
||||
}
|
||||
layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this);
|
||||
layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this);
|
||||
|
||||
// if enable timelapse, slice all layer
|
||||
if (enable_timelapse_print()) {
|
||||
if (layer_tools.wipe_tower_partitions == 0)
|
||||
wipe_tower.set_last_layer_extruder_fill(false);
|
||||
continue;
|
||||
}
|
||||
// if enable timelapse, slice all layer
|
||||
if (enable_timelapse_print()) {
|
||||
if (layer_tools.wipe_tower_partitions == 0) wipe_tower.set_last_layer_extruder_fill(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (&layer_tools == &m_wipe_tower_data.tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0)
|
||||
break;
|
||||
if (&layer_tools == &m_wipe_tower_data.tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::vector<float> flush_matrix(cast<float>(get_flush_volumes_matrix(m_config.flush_volumes_matrix.values, 0, nozzle_nums)));
|
||||
|
||||
// Extract purging volumes for each extruder pair:
|
||||
std::vector<std::vector<float>> wipe_volumes;
|
||||
for (unsigned int i = 0; i < number_of_extruders; ++i)
|
||||
wipe_volumes.push_back(std::vector<float>(flush_matrix.begin() + i * number_of_extruders, flush_matrix.begin() + (i + 1) * number_of_extruders));
|
||||
|
||||
|
||||
// BBS: priming logic is removed, so get the initial extruder by first_extruder()
|
||||
unsigned int current_extruder_id = m_wipe_tower_data.tool_ordering.first_extruder();
|
||||
for (auto &layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers
|
||||
if (!layer_tools.has_wipe_tower) continue;
|
||||
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
|
||||
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id);
|
||||
|
||||
for (const auto extruder_id : layer_tools.extruders) {
|
||||
// BBS: priming logic is removed, so no need to do toolchange for first extruder
|
||||
if (/*(first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || */extruder_id != current_extruder_id) {
|
||||
float volume_to_purge = wipe_volumes[current_extruder_id][extruder_id];
|
||||
volume_to_purge *= m_config.flush_multiplier.get_at(0);
|
||||
|
||||
// Not all of that can be used for infill purging:
|
||||
//volume_to_purge -= (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
||||
|
||||
// try to assign some infills/objects for the wiping:
|
||||
volume_to_purge = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_extruder_id, extruder_id, volume_to_purge);
|
||||
|
||||
// add back the minimal amount toforce on the wipe tower:
|
||||
//volume_to_purge += (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
||||
|
||||
// request a toolchange at the wipe tower with at least volume_to_wipe purging amount
|
||||
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height,
|
||||
current_extruder_id, extruder_id, m_config.prime_volume, volume_to_purge);
|
||||
current_extruder_id = extruder_id;
|
||||
}
|
||||
}
|
||||
layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this);
|
||||
|
||||
// if enable timelapse, slice all layer
|
||||
if (enable_timelapse_print()) {
|
||||
if (layer_tools.wipe_tower_partitions == 0)
|
||||
wipe_tower.set_last_layer_extruder_fill(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (&layer_tools == &m_wipe_tower_data.tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ static const t_config_enum_values s_keys_map_ZHopType = {
|
|||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(ZHopType)
|
||||
|
||||
static const t_config_enum_values s_keys_map_ExtruderType = {
|
||||
{ "DirectDrive", etDirectDrive },
|
||||
{ "Direct drive", etDirectDrive },
|
||||
{ "Bowden", etBowden }
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(ExtruderType)
|
||||
|
@ -404,6 +404,7 @@ std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolume
|
|||
variant_string = s_keys_names_ExtruderType[extruder_type];
|
||||
variant_string+= " ";
|
||||
variant_string+= s_keys_names_NozzleVolumeType[nozzle_volume_type];
|
||||
return variant_string;
|
||||
}
|
||||
|
||||
static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology)
|
||||
|
@ -3903,11 +3904,11 @@ void PrintConfigDef::init_fff_params()
|
|||
280.f, 280.f, 0.f, 280.f,
|
||||
280.f, 280.f, 280.f, 0.f });
|
||||
|
||||
def = this->add("flush_multiplier", coFloat);
|
||||
def = this->add("flush_multiplier", coFloats);
|
||||
def->label = L("Flush multiplier");
|
||||
def->tooltip = L("The actual flushing volumes is equal to the flush multiplier multiplied by the flushing volumes in the table.");
|
||||
def->sidetext = "";
|
||||
def->set_default_value(new ConfigOptionFloat(1.0));
|
||||
def->set_default_value(new ConfigOptionFloats{1.0});
|
||||
|
||||
// BBS
|
||||
def = this->add("prime_volume", coFloat);
|
||||
|
@ -5405,8 +5406,8 @@ int DynamicPrintConfig::get_index_for_extruder(int extruder_id, std::string id_n
|
|||
auto variant_opt = dynamic_cast<const ConfigOptionStrings*>(this->option(variant_name));
|
||||
auto id_opt = dynamic_cast<const ConfigOptionInts*>(this->option(id_name));
|
||||
if ((variant_opt != nullptr)&&(id_opt != nullptr)) {
|
||||
int v_size = variant_opt->size();
|
||||
int i_size = variant_opt->size();
|
||||
int v_size = variant_opt->values.size();
|
||||
int i_size = id_opt->values.size();
|
||||
std::string extruder_variant = get_extruder_variant_string(extruder_type, nozzle_volume_type);
|
||||
for (int index = 0; index < v_size; index++)
|
||||
{
|
||||
|
|
|
@ -1135,7 +1135,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||
((ConfigOptionFloats, flush_volumes_vector))
|
||||
// BBS: wipe tower is only used for priming
|
||||
((ConfigOptionFloat, prime_volume))
|
||||
((ConfigOptionFloat, flush_multiplier))
|
||||
((ConfigOptionFloats, flush_multiplier))
|
||||
//((ConfigOptionFloat, z_offset))
|
||||
// BBS: project filaments
|
||||
((ConfigOptionFloats, filament_colour_new))
|
||||
|
@ -1547,6 +1547,34 @@ private:
|
|||
|
||||
static uint64_t s_last_timestamp;
|
||||
};
|
||||
|
||||
// const std::vector<double> &fv_matrix: origin matrix from json
|
||||
// size_t extruder_id: -1 means single-nozzle for old file, 0 means the 1st extruder, 1 means the 2nd extruder
|
||||
template<class T>
|
||||
static std::vector<T> get_flush_volumes_matrix(const std::vector<T> &fv_matrix, size_t extruder_id = -1, size_t nozzle_nums = 1)
|
||||
{
|
||||
if (extruder_id != -1 && nozzle_nums != 1) {
|
||||
return std::vector<T>(fv_matrix.begin() + size_t(fv_matrix.size() / nozzle_nums * extruder_id + EPSILON),
|
||||
fv_matrix.begin() + size_t(fv_matrix.size() / nozzle_nums * (extruder_id + 1) + EPSILON));
|
||||
}
|
||||
return fv_matrix;
|
||||
}
|
||||
|
||||
// std::vector<double> &out_matrix:
|
||||
// const std::vector<double> &fv_matrix: the matrix of one nozzle
|
||||
// size_t extruder_id: -1 means single-nozzle for old file, 0 means the 1st extruder, 1 means the 2nd extruder
|
||||
template<class T>
|
||||
static void set_flush_volumes_matrix(std::vector<T> &out_matrix, const std::vector<T> &fv_matrix, size_t extruder_id = -1, size_t nozzle_nums = 1)
|
||||
{
|
||||
bool is_multi_extruder = false;
|
||||
if (extruder_id != -1 && nozzle_nums != 1) {
|
||||
std::copy(fv_matrix.begin(), fv_matrix.end(), out_matrix.begin() + size_t(out_matrix.size() / nozzle_nums * extruder_id + EPSILON));
|
||||
}
|
||||
else {
|
||||
out_matrix = std::vector<T>(fv_matrix.begin(), fv_matrix.end());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
// Serialization through the Cereal library
|
||||
|
|
|
@ -484,8 +484,11 @@ void Sidebar::priv::hide_rich_tip(wxButton* btn)
|
|||
}
|
||||
#endif
|
||||
|
||||
std::vector<int> get_min_flush_volumes(const DynamicPrintConfig& full_config)
|
||||
std::vector<int> get_min_flush_volumes(const DynamicPrintConfig &full_config, size_t nozzle_id)
|
||||
{
|
||||
//todo multi_extruder:
|
||||
nozzle_id = 0;
|
||||
|
||||
std::vector<int>extra_flush_volumes;
|
||||
//const auto& full_config = wxGetApp().preset_bundle->full_config();
|
||||
//auto& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
|
@ -502,7 +505,7 @@ std::vector<int> get_min_flush_volumes(const DynamicPrintConfig& full_config)
|
|||
const ConfigOptionBools* long_retractions_when_cut_opt = full_config.option<ConfigOptionBools>("long_retractions_when_cut");
|
||||
bool machine_activated = false;
|
||||
if (long_retractions_when_cut_opt) {
|
||||
machine_activated = long_retractions_when_cut_opt->values[0] == 1;
|
||||
machine_activated = long_retractions_when_cut_opt->values[nozzle_id] == 1;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": get long_retractions_when_cut from config, value=%1%, activated=%2%")%long_retractions_when_cut_opt->values[0] %machine_activated;
|
||||
}
|
||||
|
||||
|
@ -529,7 +532,7 @@ std::vector<int> get_min_flush_volumes(const DynamicPrintConfig& full_config)
|
|||
|
||||
for (size_t idx = 0; idx < filament_size; ++idx) {
|
||||
int extra_flush_volume = nozzle_volume_val;
|
||||
int retract_length = machine_enabled_level && machine_activated ? printer_retraction_distance_when_cut[0] : 0;
|
||||
int retract_length = machine_enabled_level && machine_activated ? printer_retraction_distance_when_cut[nozzle_id] : 0;
|
||||
|
||||
unsigned char filament_activated = filament_long_retractions_when_cut[idx];
|
||||
double filament_retract_length = filament_retraction_distance_when_cut[idx];
|
||||
|
@ -540,7 +543,7 @@ std::vector<int> get_min_flush_volumes(const DynamicPrintConfig& full_config)
|
|||
if (!std::isnan(filament_retract_length))
|
||||
retract_length = (int)filament_retraction_distance_when_cut[idx];
|
||||
else
|
||||
retract_length = printer_retraction_distance_when_cut[0];
|
||||
retract_length = printer_retraction_distance_when_cut[nozzle_id];
|
||||
}
|
||||
|
||||
extra_flush_volume -= PI * 1.75 * 1.75 / 4 * retract_length;
|
||||
|
@ -1040,19 +1043,30 @@ Sidebar::Sidebar(Plater *parent)
|
|||
auto& project_config = wxGetApp().preset_bundle->project_config;
|
||||
const std::vector<double>& init_matrix = (project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values;
|
||||
const std::vector<double>& init_extruders = (project_config.option<ConfigOptionFloats>("flush_volumes_vector"))->values;
|
||||
ConfigOptionFloat* flush_multi_opt = project_config.option<ConfigOptionFloat>("flush_multiplier");
|
||||
float flush_multiplier = flush_multi_opt ? flush_multi_opt->getFloat() : 1.f;
|
||||
|
||||
|
||||
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
|
||||
const auto& full_config = wxGetApp().preset_bundle->full_config();
|
||||
const auto& extra_flush_volumes = get_min_flush_volumes(full_config);
|
||||
WipingDialog dlg(parent, cast<float>(init_matrix), cast<float>(init_extruders), extruder_colours, extra_flush_volumes, flush_multiplier);
|
||||
const auto& extra_flush_volumes = get_min_flush_volumes(full_config, 0); // todo multi_extruder: always display nozzle 1
|
||||
|
||||
size_t nozzle_nums = full_config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
|
||||
std::vector<float> flush_multiplier;
|
||||
ConfigOptionFloats *flush_multi_opt = project_config.option<ConfigOptionFloats>("flush_multiplier");
|
||||
if (flush_multi_opt)
|
||||
flush_multiplier = cast<float>(flush_multi_opt->values);
|
||||
else {
|
||||
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) {
|
||||
flush_multiplier.push_back(1.f);
|
||||
}
|
||||
}
|
||||
WipingDialog dlg(parent, cast<float>(init_matrix), cast<float>(init_extruders), extruder_colours, extra_flush_volumes, flush_multiplier, nozzle_nums);
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
std::vector<float> matrix = dlg.get_matrix();
|
||||
std::vector<float> extruders = dlg.get_extruders();
|
||||
std::vector<float> flush_multipliers = dlg.get_flush_multiplier_vector();
|
||||
(project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values = std::vector<double>(matrix.begin(), matrix.end());
|
||||
(project_config.option<ConfigOptionFloats>("flush_volumes_vector"))->values = std::vector<double>(extruders.begin(), extruders.end());
|
||||
(project_config.option<ConfigOptionFloat>("flush_multiplier"))->set(new ConfigOptionFloat(dlg.get_flush_multiplier()));
|
||||
(project_config.option<ConfigOptionFloats>("flush_multiplier"))->values = std::vector<double>(flush_multipliers.begin(), flush_multipliers.end());
|
||||
|
||||
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
|
||||
|
||||
|
@ -2223,94 +2237,96 @@ void Sidebar::auto_calc_flushing_volumes(const int modify_id)
|
|||
auto& ams_multi_color_filament = preset_bundle->ams_multi_color_filment;
|
||||
auto& ams_filament_list = preset_bundle->filament_ams_list;
|
||||
|
||||
const std::vector<double>& init_matrix = (project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values;
|
||||
const std::vector<double>& init_extruders = (project_config.option<ConfigOptionFloats>("flush_volumes_vector"))->values;
|
||||
size_t nozzle_nums = preset_bundle->full_config().option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id)
|
||||
{
|
||||
std::vector<double> init_matrix = get_flush_volumes_matrix((project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values, nozzle_id, nozzle_nums);
|
||||
|
||||
const std::vector<int>& min_flush_volumes= get_min_flush_volumes(full_config);
|
||||
|
||||
ConfigOptionFloat* flush_multi_opt = project_config.option<ConfigOptionFloat>("flush_multiplier");
|
||||
float flush_multiplier = flush_multi_opt ? flush_multi_opt->getFloat() : 1.f;
|
||||
std::vector<double> matrix = init_matrix;
|
||||
int m_max_flush_volume = Slic3r::g_max_flush_volume;
|
||||
unsigned int m_number_of_extruders = (int)(sqrt(init_matrix.size()) + 0.001);
|
||||
|
||||
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
|
||||
std::vector<std::vector<wxColour>> multi_colours;
|
||||
|
||||
// Support for multi-color filament
|
||||
for (int i = 0; i < extruder_colours.size(); ++i) {
|
||||
std::vector<wxColour> single_filament;
|
||||
if (i < ams_multi_color_filament.size()) {
|
||||
if (!ams_multi_color_filament[i].empty()) {
|
||||
std::vector<std::string> colors = ams_multi_color_filament[i];
|
||||
for (int j = 0; j < colors.size(); ++j) {
|
||||
single_filament.push_back(wxColour(colors[j]));
|
||||
const std::vector<int>& min_flush_volumes= get_min_flush_volumes(full_config, nozzle_id);
|
||||
|
||||
ConfigOptionFloat* flush_multi_opt = project_config.option<ConfigOptionFloat>("flush_multiplier");
|
||||
float flush_multiplier = flush_multi_opt ? flush_multi_opt->getFloat() : 1.f;
|
||||
std::vector<double> matrix = init_matrix;
|
||||
int m_max_flush_volume = Slic3r::g_max_flush_volume;
|
||||
unsigned int m_number_of_extruders = (int)(sqrt(init_matrix.size()) + 0.001);
|
||||
|
||||
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
|
||||
std::vector<std::vector<wxColour>> multi_colours;
|
||||
|
||||
// Support for multi-color filament
|
||||
for (int i = 0; i < extruder_colours.size(); ++i) {
|
||||
std::vector<wxColour> single_filament;
|
||||
if (i < ams_multi_color_filament.size()) {
|
||||
if (!ams_multi_color_filament[i].empty()) {
|
||||
std::vector<std::string> colors = ams_multi_color_filament[i];
|
||||
for (int j = 0; j < colors.size(); ++j) {
|
||||
single_filament.push_back(wxColour(colors[j]));
|
||||
}
|
||||
multi_colours.push_back(single_filament);
|
||||
continue;
|
||||
}
|
||||
multi_colours.push_back(single_filament);
|
||||
continue;
|
||||
}
|
||||
|
||||
single_filament.push_back(wxColour(extruder_colours[i]));
|
||||
multi_colours.push_back(single_filament);
|
||||
}
|
||||
|
||||
single_filament.push_back(wxColour(extruder_colours[i]));
|
||||
multi_colours.push_back(single_filament);
|
||||
}
|
||||
|
||||
if (modify_id >= 0 && modify_id < multi_colours.size()) {
|
||||
for (int i = 0; i < multi_colours.size(); ++i) {
|
||||
// from to modify
|
||||
int from_idx = i;
|
||||
if (from_idx != modify_id) {
|
||||
Slic3r::FlushVolCalculator calculator(min_flush_volumes[from_idx], m_max_flush_volume);
|
||||
int flushing_volume = 0;
|
||||
bool is_from_support = is_support_filament(from_idx);
|
||||
bool is_to_support = is_support_filament(modify_id);
|
||||
if (is_to_support) {
|
||||
flushing_volume = Slic3r::g_flush_volume_to_support;
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < multi_colours[from_idx].size(); ++j) {
|
||||
const wxColour& from = multi_colours[from_idx][j];
|
||||
for (int k = 0; k < multi_colours[modify_id].size(); ++k) {
|
||||
const wxColour& to = multi_colours[modify_id][k];
|
||||
int volume = calculator.calc_flush_vol(from.Alpha(), from.Red(), from.Green(), from.Blue(), to.Alpha(), to.Red(), to.Green(), to.Blue());
|
||||
flushing_volume = std::max(flushing_volume, volume);
|
||||
}
|
||||
|
||||
if (modify_id >= 0 && modify_id < multi_colours.size()) {
|
||||
for (int i = 0; i < multi_colours.size(); ++i) {
|
||||
// from to modify
|
||||
int from_idx = i;
|
||||
if (from_idx != modify_id) {
|
||||
Slic3r::FlushVolCalculator calculator(min_flush_volumes[from_idx], m_max_flush_volume);
|
||||
int flushing_volume = 0;
|
||||
bool is_from_support = is_support_filament(from_idx);
|
||||
bool is_to_support = is_support_filament(modify_id);
|
||||
if (is_to_support) {
|
||||
flushing_volume = Slic3r::g_flush_volume_to_support;
|
||||
}
|
||||
if (is_from_support)
|
||||
flushing_volume = std::max(flushing_volume, Slic3r::g_min_flush_volume_from_support);
|
||||
}
|
||||
matrix[m_number_of_extruders * from_idx + modify_id] = flushing_volume;
|
||||
}
|
||||
|
||||
// modify to to
|
||||
int to_idx = i;
|
||||
if (to_idx != modify_id) {
|
||||
Slic3r::FlushVolCalculator calculator(min_flush_volumes[modify_id], m_max_flush_volume);
|
||||
bool is_from_support = is_support_filament(modify_id);
|
||||
bool is_to_support = is_support_filament(to_idx);
|
||||
int flushing_volume = 0;
|
||||
if (is_to_support) {
|
||||
flushing_volume = Slic3r::g_flush_volume_to_support;
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < multi_colours[modify_id].size(); ++j) {
|
||||
const wxColour& from = multi_colours[modify_id][j];
|
||||
for (int k = 0; k < multi_colours[to_idx].size(); ++k) {
|
||||
const wxColour& to = multi_colours[to_idx][k];
|
||||
int volume = calculator.calc_flush_vol(from.Alpha(), from.Red(), from.Green(), from.Blue(), to.Alpha(), to.Red(), to.Green(), to.Blue());
|
||||
flushing_volume = std::max(flushing_volume, volume);
|
||||
else {
|
||||
for (int j = 0; j < multi_colours[from_idx].size(); ++j) {
|
||||
const wxColour& from = multi_colours[from_idx][j];
|
||||
for (int k = 0; k < multi_colours[modify_id].size(); ++k) {
|
||||
const wxColour& to = multi_colours[modify_id][k];
|
||||
int volume = calculator.calc_flush_vol(from.Alpha(), from.Red(), from.Green(), from.Blue(), to.Alpha(), to.Red(), to.Green(), to.Blue());
|
||||
flushing_volume = std::max(flushing_volume, volume);
|
||||
}
|
||||
}
|
||||
if (is_from_support)
|
||||
flushing_volume = std::max(flushing_volume, Slic3r::g_min_flush_volume_from_support);
|
||||
}
|
||||
matrix[m_number_of_extruders * from_idx + modify_id] = flushing_volume;
|
||||
}
|
||||
|
||||
// modify to to
|
||||
int to_idx = i;
|
||||
if (to_idx != modify_id) {
|
||||
Slic3r::FlushVolCalculator calculator(min_flush_volumes[modify_id], m_max_flush_volume);
|
||||
bool is_from_support = is_support_filament(modify_id);
|
||||
bool is_to_support = is_support_filament(to_idx);
|
||||
int flushing_volume = 0;
|
||||
if (is_to_support) {
|
||||
flushing_volume = Slic3r::g_flush_volume_to_support;
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < multi_colours[modify_id].size(); ++j) {
|
||||
const wxColour& from = multi_colours[modify_id][j];
|
||||
for (int k = 0; k < multi_colours[to_idx].size(); ++k) {
|
||||
const wxColour& to = multi_colours[to_idx][k];
|
||||
int volume = calculator.calc_flush_vol(from.Alpha(), from.Red(), from.Green(), from.Blue(), to.Alpha(), to.Red(), to.Green(), to.Blue());
|
||||
flushing_volume = std::max(flushing_volume, volume);
|
||||
}
|
||||
}
|
||||
if (is_from_support)
|
||||
flushing_volume = std::max(flushing_volume, Slic3r::g_min_flush_volume_from_support);
|
||||
|
||||
matrix[m_number_of_extruders * modify_id + to_idx] = flushing_volume;
|
||||
}
|
||||
if (is_from_support)
|
||||
flushing_volume = std::max(flushing_volume, Slic3r::g_min_flush_volume_from_support);
|
||||
|
||||
matrix[m_number_of_extruders * modify_id + to_idx] = flushing_volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
set_flush_volumes_matrix((project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values, matrix, nozzle_id, nozzle_nums);
|
||||
}
|
||||
(project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values = std::vector<double>(matrix.begin(), matrix.end());
|
||||
|
||||
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
|
||||
|
||||
wxGetApp().plater()->update_project_dirty_from_presets();
|
||||
|
@ -13160,6 +13176,13 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
|
|||
bool bed_shape_changed = false;
|
||||
//bool print_sequence_changed = false;
|
||||
t_config_option_keys diff_keys = p->config->diff(config);
|
||||
|
||||
std::string old_model_id;
|
||||
auto * printer_model = p->config->opt<ConfigOptionString>("printer_model");
|
||||
if (printer_model != nullptr && !printer_model->value.empty()) {
|
||||
old_model_id = printer_model->value;
|
||||
}
|
||||
|
||||
for (auto opt_key : diff_keys) {
|
||||
if (opt_key == "filament_colour") {
|
||||
update_scheduled = true; // update should be scheduled (for update 3DScene) #2738
|
||||
|
@ -13218,6 +13241,8 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
|
|||
}
|
||||
else if (opt_key == "printer_model") {
|
||||
p->reset_gcode_toolpaths();
|
||||
update_flush_volume_matrix(config, old_model_id);
|
||||
|
||||
// update to force bed selection(for texturing)
|
||||
bed_shape_changed = true;
|
||||
update_scheduled = true;
|
||||
|
@ -13241,6 +13266,35 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
|
|||
this->p->schedule_background_process();
|
||||
}
|
||||
|
||||
void Plater::update_flush_volume_matrix(const Slic3r::DynamicPrintConfig& config, const std::string& old_model_id)
|
||||
{
|
||||
auto is_multi_extruder_printer = [](const std::string &model_id) {
|
||||
return model_id == "Bambu Lab O1 Dual";
|
||||
};
|
||||
|
||||
auto *printer_model = config.opt<ConfigOptionString>("printer_model");
|
||||
if (printer_model != nullptr && !printer_model->value.empty()) {
|
||||
size_t nozzle_nums = wxGetApp().preset_bundle->full_config().option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
if (!is_multi_extruder_printer(old_model_id) && is_multi_extruder_printer(printer_model->value)) {
|
||||
Slic3r::DynamicPrintConfig *project_config = &wxGetApp().preset_bundle->project_config;
|
||||
std::vector<double> flush_volume_mtx = get_flush_volumes_matrix(project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values, -1, nozzle_nums);
|
||||
flush_volume_mtx.insert(flush_volume_mtx.end(), flush_volume_mtx.begin(), flush_volume_mtx.end());
|
||||
set_flush_volumes_matrix(project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values, flush_volume_mtx, -1, nozzle_nums);
|
||||
|
||||
double first_value = project_config->option<ConfigOptionFloats>("flush_multiplier")->values.at(0);
|
||||
project_config->option<ConfigOptionFloats>("flush_multiplier")->values = std::vector<double>({first_value, 1.0});
|
||||
}
|
||||
else if (is_multi_extruder_printer(old_model_id) && !is_multi_extruder_printer(printer_model->value)) {
|
||||
Slic3r::DynamicPrintConfig *project_config = &wxGetApp().preset_bundle->project_config;
|
||||
std::vector<double> flush_volume_mtx = get_flush_volumes_matrix(project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values, 0, nozzle_nums);
|
||||
set_flush_volumes_matrix(project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values, flush_volume_mtx, -1, nozzle_nums);
|
||||
|
||||
double first_value = project_config->option<ConfigOptionFloats>("flush_multiplier")->values.at(0);
|
||||
project_config->option<ConfigOptionFloats>("flush_multiplier")->values = std::vector<double>({first_value});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Plater::set_bed_shape() const
|
||||
{
|
||||
std::string texture_filename;
|
||||
|
|
|
@ -608,6 +608,8 @@ public:
|
|||
const Mouse3DController& get_mouse3d_controller() const;
|
||||
Mouse3DController& get_mouse3d_controller();
|
||||
|
||||
//BBS: update when switch muilti_extruder printer
|
||||
void update_flush_volume_matrix(const Slic3r::DynamicPrintConfig &config, const std::string &old_model_id);
|
||||
//BBS: add bed exclude area
|
||||
void set_bed_shape() const;
|
||||
void set_bed_shape(const Pointfs& shape, const Pointfs& exclude_area, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const;
|
||||
|
@ -791,7 +793,7 @@ private:
|
|||
bool m_was_scheduled;
|
||||
};
|
||||
|
||||
std::vector<int> get_min_flush_volumes(const DynamicPrintConfig& full_config);
|
||||
std::vector<int> get_min_flush_volumes(const DynamicPrintConfig &full_config, size_t nozzle_id);
|
||||
std::string check_boolean_possible(const std::vector<const ModelVolume*>& volumes);
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -168,6 +168,13 @@ wxBoxSizer* WipingPanel::create_calc_btn_sizer(wxWindow* parent) {
|
|||
btn_sizer->Add(calc_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, BTN_GAP);
|
||||
calc_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { calc_flushing_volumes(); });
|
||||
|
||||
ComboBox *extruder_combo = new ComboBox(parent, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(100), FromDIP(24)), 0, nullptr, wxCB_READONLY);
|
||||
extruder_combo->AppendString(_L("extruder 1"));
|
||||
extruder_combo->AppendString(_L("extruder 2"));
|
||||
extruder_combo->SetSelection(0);
|
||||
extruder_combo->Bind(wxEVT_COMBOBOX, &WipingPanel::on_select_extruder, this);
|
||||
btn_sizer->Add(extruder_combo);
|
||||
|
||||
return btn_sizer;
|
||||
}
|
||||
void WipingDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||
|
@ -194,7 +201,7 @@ void WipingDialog::on_dpi_changed(const wxRect &suggested_rect)
|
|||
|
||||
// Parent dialog for purging volume adjustments - it fathers WipingPanel widget (that contains all controls) and a button to toggle simple/advanced mode:
|
||||
WipingDialog::WipingDialog(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours,
|
||||
const std::vector<int>&extra_flush_volume, float flush_multiplier)
|
||||
const std::vector<int>&extra_flush_volume, const std::vector<float>& flush_multiplier, size_t nozzle_nums)
|
||||
: DPIDialog(parent ? parent : static_cast<wxWindow *>(wxGetApp().mainframe),
|
||||
wxID_ANY,
|
||||
_(L("Flushing volumes for filament change")),
|
||||
|
@ -212,7 +219,7 @@ WipingDialog::WipingDialog(wxWindow* parent, const std::vector<float>& matrix, c
|
|||
this->SetMinSize(wxSize(MIN_WIPING_DIALOG_WIDTH, -1));
|
||||
|
||||
|
||||
m_panel_wiping = new WipingPanel(this, matrix, extruders, extruder_colours, nullptr, extra_flush_volume, flush_multiplier);
|
||||
m_panel_wiping = new WipingPanel(this, matrix, extruders, 0, extruder_colours, nullptr, extra_flush_volume, flush_multiplier, nozzle_nums);
|
||||
|
||||
auto main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
|
||||
|
@ -293,19 +300,29 @@ void WipingPanel::create_panels(wxWindow* parent, const int num) {
|
|||
}
|
||||
|
||||
// This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers)
|
||||
WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours, Button* calc_button,
|
||||
const std::vector<int>& extra_flush_volume, float flush_multiplier)
|
||||
: wxPanel(parent,wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxBORDER_RAISED*/)
|
||||
,m_matrix(matrix), m_min_flush_volume(extra_flush_volume), m_max_flush_volume(Slic3r::g_max_flush_volume)
|
||||
WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders,
|
||||
size_t cur_extruder_id,
|
||||
const std::vector<std::string>& extruder_colours, Button* calc_button,
|
||||
const std::vector<int>& extra_flush_volume, const std::vector<float>& flush_multiplier, size_t nozzle_nums)
|
||||
: wxPanel(parent,wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxBORDER_RAISED*/)
|
||||
, m_flush_multiplier(flush_multiplier)
|
||||
, m_matrix(matrix)
|
||||
, m_cur_extruder_id(cur_extruder_id)
|
||||
, m_min_flush_volume(extra_flush_volume)
|
||||
, m_max_flush_volume(Slic3r::g_max_flush_volume)
|
||||
, m_nozzle_nums(nozzle_nums)
|
||||
{
|
||||
m_number_of_extruders = (int)(sqrt(matrix.size())+0.001);
|
||||
m_number_of_extruders = (unsigned int)extruder_colours.size();
|
||||
|
||||
generate_display_matrix();
|
||||
assert(m_display_matrix.size() == extruders.size() ^ 2);
|
||||
|
||||
for (const std::string& color : extruder_colours) {
|
||||
//unsigned char rgb[3];
|
||||
//Slic3r::GUI::BitmapCache::parse_color(color, rgb);
|
||||
m_colours.push_back(wxColor(color));
|
||||
}
|
||||
auto sizer_width = (int)((sqrt(matrix.size())) * ITEM_WIDTH() + (sqrt(matrix.size()) + 1) * HEADER_BEG_PADDING);
|
||||
auto sizer_width = (int)((sqrt(m_display_matrix.size())) * ITEM_WIDTH() + (sqrt(m_display_matrix.size()) + 1) * HEADER_BEG_PADDING);
|
||||
sizer_width = sizer_width > MIN_WIPING_DIALOG_WIDTH ? sizer_width : MIN_WIPING_DIALOG_WIDTH;
|
||||
// Create two switched panels with their own sizers
|
||||
m_sizer_simple = new wxBoxSizer(wxVERTICAL);
|
||||
|
@ -341,7 +358,7 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
|||
edit_boxes[i][j]->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent&) {});
|
||||
}
|
||||
else {
|
||||
edit_boxes[i][j]->SetValue(wxString("") << int(m_matrix[m_number_of_extruders * j + i] * flush_multiplier));
|
||||
edit_boxes[i][j]->SetValue(wxString("") << int(m_display_matrix[m_number_of_extruders * j + i] * m_flush_multiplier[m_cur_extruder_id]));
|
||||
|
||||
edit_boxes[i][j]->Bind(wxEVT_TEXT, [this, i, j](wxCommandEvent& e) {
|
||||
wxString str = edit_boxes[i][j]->GetValue();
|
||||
|
@ -358,7 +375,7 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
|||
auto on_apply_text_modify = [this, i, j](wxEvent &e) {
|
||||
wxString str = edit_boxes[i][j]->GetValue();
|
||||
int value = wxAtoi(str);
|
||||
m_matrix[m_number_of_extruders * j + i] = value / get_flush_multiplier();
|
||||
m_display_matrix[m_number_of_extruders * j + i] = value / get_flush_multiplier();
|
||||
this->update_warning_texts();
|
||||
e.Skip();
|
||||
};
|
||||
|
@ -434,14 +451,18 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
|||
if (multiplier < g_min_flush_multiplier || multiplier > g_max_flush_multiplier) {
|
||||
str = wxString::Format(("%.2f"), multiplier < g_min_flush_multiplier ? g_min_flush_multiplier : g_max_flush_multiplier);
|
||||
m_flush_multiplier_ebox->SetValue(str);
|
||||
m_flush_multiplier[m_cur_extruder_id] = wxAtof(m_flush_multiplier_ebox->GetValue());
|
||||
MessageDialog dlg(nullptr,
|
||||
wxString::Format(_L("The multiplier should be in range [%.2f, %.2f]."), g_min_flush_multiplier, g_max_flush_multiplier),
|
||||
_L("Warning"), wxICON_WARNING | wxOK);
|
||||
dlg.ShowModal();
|
||||
}
|
||||
else {
|
||||
m_flush_multiplier[m_cur_extruder_id] = multiplier;
|
||||
}
|
||||
for (unsigned int i = 0; i < m_number_of_extruders; ++i) {
|
||||
for (unsigned int j = 0; j < m_number_of_extruders; ++j) {
|
||||
edit_boxes[i][j]->SetValue(to_string(int(m_matrix[m_number_of_extruders * j + i] * multiplier)));
|
||||
edit_boxes[i][j]->SetValue(to_string(int(m_display_matrix[m_number_of_extruders * j + i] * multiplier)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,7 +477,7 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
|||
param_sizer->Add(flush_multiplier_title, 0, wxALIGN_CENTER | wxALL, 0);
|
||||
param_sizer->AddSpacer(FromDIP(5));
|
||||
m_flush_multiplier_ebox = new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(50), -1), wxTE_PROCESS_ENTER);
|
||||
m_flush_multiplier_ebox->SetValue(wxString::Format(("%.2f"), flush_multiplier));
|
||||
m_flush_multiplier_ebox->SetValue(wxString::Format(("%.2f"), m_flush_multiplier[m_cur_extruder_id]));
|
||||
m_flush_multiplier_ebox->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
|
||||
param_sizer->Add(m_flush_multiplier_ebox, 0, wxALIGN_CENTER | wxALL, 0);
|
||||
param_sizer->AddStretchSpacer(1);
|
||||
|
@ -475,6 +496,10 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
|||
if (multiplier < g_min_flush_multiplier || multiplier > g_max_flush_multiplier) {
|
||||
str = wxString::Format(("%.2f"), multiplier < g_min_flush_multiplier ? g_min_flush_multiplier : g_max_flush_multiplier);
|
||||
m_flush_multiplier_ebox->SetValue(str);
|
||||
m_flush_multiplier[m_cur_extruder_id] = wxAtof(m_flush_multiplier_ebox->GetValue());
|
||||
}
|
||||
else {
|
||||
m_flush_multiplier[m_cur_extruder_id] = multiplier;
|
||||
}
|
||||
m_flush_multiplier_ebox->SetInsertionPointEnd();
|
||||
});
|
||||
|
@ -677,7 +702,7 @@ void WipingPanel::calc_flushing_volumes()
|
|||
}
|
||||
}
|
||||
|
||||
m_matrix[m_number_of_extruders * from_idx + to_idx] = flushing_volume;
|
||||
m_display_matrix[m_number_of_extruders * from_idx + to_idx] = flushing_volume;
|
||||
flushing_volume = int(flushing_volume * get_flush_multiplier());
|
||||
edit_boxes[to_idx][from_idx]->SetValue(std::to_string(flushing_volume));
|
||||
}
|
||||
|
@ -714,7 +739,9 @@ std::vector<float> WipingPanel::read_matrix_values() {
|
|||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
m_display_matrix = output;
|
||||
back_matrix();
|
||||
return m_matrix;
|
||||
}
|
||||
|
||||
// Reads values from simple mode to save them for next time:
|
||||
|
@ -737,7 +764,46 @@ void WipingPanel::fill_in_matrix() {
|
|||
}
|
||||
}
|
||||
|
||||
void WipingPanel::generate_display_matrix()
|
||||
{
|
||||
m_display_matrix = get_flush_volumes_matrix(m_matrix, m_cur_extruder_id, m_nozzle_nums);
|
||||
}
|
||||
|
||||
void WipingPanel::back_matrix()
|
||||
{
|
||||
set_flush_volumes_matrix(m_matrix, m_display_matrix, m_cur_extruder_id, m_nozzle_nums);
|
||||
}
|
||||
|
||||
void WipingPanel::update_table()
|
||||
{
|
||||
for (unsigned int i = 0; i < m_number_of_extruders; ++i) {
|
||||
for (unsigned int j = 0; j < m_number_of_extruders; ++j) {
|
||||
if (i == j) {
|
||||
edit_boxes[i][j]->SetValue(wxString("0"));
|
||||
edit_boxes[i][j]->SetEditable(false);
|
||||
} else {
|
||||
edit_boxes[i][j]->SetValue(wxString("") << int(m_display_matrix[m_number_of_extruders * j + i] * m_flush_multiplier[m_cur_extruder_id]));
|
||||
}
|
||||
}
|
||||
}
|
||||
wxString str = wxString::Format(("%.2f"), m_flush_multiplier[m_cur_extruder_id]);
|
||||
m_flush_multiplier_ebox->SetValue(str);
|
||||
update_warning_texts();
|
||||
}
|
||||
|
||||
void WipingPanel::on_select_extruder(wxCommandEvent &evt)
|
||||
{
|
||||
ComboBox *comboBox = dynamic_cast<ComboBox *>(evt.GetEventObject());
|
||||
if (comboBox) {
|
||||
int selection = comboBox->GetSelection();
|
||||
if (m_cur_extruder_id != selection) {
|
||||
read_matrix_values();
|
||||
m_cur_extruder_id = selection;
|
||||
generate_display_matrix();
|
||||
update_table();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function to check if simple and advanced settings are matching
|
||||
bool WipingPanel::advanced_matches_simple() {
|
||||
|
|
|
@ -15,8 +15,9 @@ class Label;
|
|||
class WipingPanel : public wxPanel {
|
||||
public:
|
||||
// BBS
|
||||
WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours, Button* calc_button,
|
||||
const std::vector<int>& extra_flush_volume, float flush_multiplier);
|
||||
WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, size_t cur_extruder_id,
|
||||
const std::vector<std::string>& extruder_colours, Button* calc_button,
|
||||
const std::vector<int>& extra_flush_volume, const std::vector<float>& flush_multiplier, size_t nozzle_nums);
|
||||
std::vector<float> read_matrix_values();
|
||||
std::vector<float> read_extruders_values();
|
||||
void toggle_advanced(bool user_action = false);
|
||||
|
@ -33,7 +34,13 @@ public:
|
|||
return wxAtof(m_flush_multiplier_ebox->GetValue());
|
||||
}
|
||||
|
||||
std::vector<float> get_flush_multiplier_vector() { return m_flush_multiplier; }
|
||||
|
||||
private:
|
||||
void on_select_extruder(wxCommandEvent &evt);
|
||||
void generate_display_matrix(); // generate display_matrix frem matrix
|
||||
void back_matrix();
|
||||
void update_table(); // if matrix is modified update the table
|
||||
void fill_in_matrix();
|
||||
bool advanced_matches_simple();
|
||||
int calc_flushing_volume(const wxColour& from, const wxColour& to,int min_flush_volume);
|
||||
|
@ -64,7 +71,11 @@ private:
|
|||
wxTextCtrl* m_flush_multiplier_ebox = nullptr;
|
||||
wxStaticText* m_min_flush_label = nullptr;
|
||||
|
||||
std::vector<float> m_flush_multiplier;
|
||||
std::vector<float> m_matrix;
|
||||
std::vector<float> m_display_matrix;
|
||||
size_t m_cur_extruder_id;
|
||||
size_t m_nozzle_nums;
|
||||
};
|
||||
|
||||
|
||||
|
@ -75,7 +86,7 @@ class WipingDialog : public Slic3r::GUI::DPIDialog
|
|||
{
|
||||
public:
|
||||
WipingDialog(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours,
|
||||
const std::vector<int>&extra_flush_volume,float flush_multiplier);
|
||||
const std::vector<int>&extra_flush_volume, const std::vector<float>& flush_multiplier, size_t nozzle_nums);
|
||||
std::vector<float> get_matrix() const { return m_output_matrix; }
|
||||
std::vector<float> get_extruders() const { return m_output_extruders; }
|
||||
wxBoxSizer* create_btn_sizer(long flags);
|
||||
|
@ -88,6 +99,12 @@ public:
|
|||
return m_panel_wiping->get_flush_multiplier();
|
||||
}
|
||||
|
||||
std::vector<float> get_flush_multiplier_vector() const {
|
||||
if (m_panel_wiping == nullptr)
|
||||
return {1.f, 1.f};
|
||||
return m_panel_wiping->get_flush_multiplier_vector();
|
||||
}
|
||||
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue