|
|
|
@ -487,7 +487,19 @@ void Tab::create_preset_tab()
|
|
|
|
|
|
|
|
|
|
m_tabctrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this);
|
|
|
|
|
|
|
|
|
|
m_main_sizer->Add(m_tabctrl, 1, wxEXPAND | wxALL, 0 );
|
|
|
|
|
m_main_sizer->Add(m_tabctrl, 0, wxEXPAND | wxALL, 0 );
|
|
|
|
|
|
|
|
|
|
if (dynamic_cast<TabPrint *>(this)) {
|
|
|
|
|
m_extruder_switch = new SwitchButton(panel);
|
|
|
|
|
m_extruder_switch->SetMaxSize({em_unit(this) * 24, -1});
|
|
|
|
|
m_extruder_switch->SetLabels(_L("Left"), _L("Right"));
|
|
|
|
|
m_extruder_switch->Bind(wxEVT_TOGGLEBUTTON, [this] (auto & evt) {
|
|
|
|
|
evt.Skip();
|
|
|
|
|
dynamic_cast<TabPrint *>(this)->switch_excluder(evt.GetInt());
|
|
|
|
|
reload_config();
|
|
|
|
|
});
|
|
|
|
|
m_main_sizer->Add(m_extruder_switch, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->SetSizer(m_main_sizer);
|
|
|
|
|
//this->Layout();
|
|
|
|
@ -805,44 +817,21 @@ void Tab::decorate()
|
|
|
|
|
m_active_page->refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> Tab::filter_diff_option(const std::vector<std::string> &options)
|
|
|
|
|
void Tab::filter_diff_option(std::vector<std::string> &options)
|
|
|
|
|
{
|
|
|
|
|
auto get_name_and_index = [](const std::string& value) -> std::pair<std::string, int>{
|
|
|
|
|
size_t pos = value.find("#");
|
|
|
|
|
if (pos != std::string::npos) {
|
|
|
|
|
std::string param_name = value.substr(0, pos);
|
|
|
|
|
std::string number_str = value.substr(pos + 1);
|
|
|
|
|
int index = 0;
|
|
|
|
|
if (!number_str.empty()) {
|
|
|
|
|
index = std::stoi(number_str);
|
|
|
|
|
}
|
|
|
|
|
return std::make_pair(param_name, index);
|
|
|
|
|
}
|
|
|
|
|
return std::make_pair(value, -1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> diff_options;
|
|
|
|
|
for (std::string option : options) {
|
|
|
|
|
auto name_to_index = get_name_and_index(option);
|
|
|
|
|
if (name_to_index.second == -1) {
|
|
|
|
|
diff_options.emplace_back(option);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t nozzle_nums = wxGetApp().preset_bundle->get_printer_extruder_count();
|
|
|
|
|
std::vector<int> support_indexes;
|
|
|
|
|
for (size_t i = 0; i < nozzle_nums; ++i) {
|
|
|
|
|
support_indexes.push_back(get_extruder_idx(*m_config, name_to_index.first, i));
|
|
|
|
|
}
|
|
|
|
|
auto iter = std::find(support_indexes.begin(), support_indexes.end(), name_to_index.second);
|
|
|
|
|
if (iter != support_indexes.end()) {
|
|
|
|
|
int extruder_id = std::distance(support_indexes.begin(), iter);
|
|
|
|
|
std::string name_to_extruder_id = name_to_index.first + "#" + std::to_string(extruder_id);
|
|
|
|
|
diff_options.emplace_back(name_to_extruder_id);
|
|
|
|
|
for (auto &opt : options) {
|
|
|
|
|
if (opt.find_last_of('#') == std::string::npos) continue;
|
|
|
|
|
bool found = false;
|
|
|
|
|
for (auto page : m_pages) {
|
|
|
|
|
if (auto iter = page->m_opt_id_map.find(opt); iter != page->m_opt_id_map.end()) {
|
|
|
|
|
opt = iter->second;
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return diff_options;
|
|
|
|
|
if (!found) opt.clear();
|
|
|
|
|
}
|
|
|
|
|
options.erase(std::remove(options.begin(), options.end(), ""), options.end());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update UI according to changes
|
|
|
|
@ -865,8 +854,8 @@ void Tab::update_changed_ui()
|
|
|
|
|
for (auto& it : m_options_list)
|
|
|
|
|
it.second = m_opt_status_value;
|
|
|
|
|
|
|
|
|
|
dirty_options = filter_diff_option(dirty_options);
|
|
|
|
|
nonsys_options = filter_diff_option(nonsys_options);
|
|
|
|
|
filter_diff_option(dirty_options);
|
|
|
|
|
filter_diff_option(nonsys_options);
|
|
|
|
|
|
|
|
|
|
for (auto opt_key : dirty_options) {
|
|
|
|
|
m_options_list[opt_key] &= ~osInitValue;
|
|
|
|
@ -1027,7 +1016,7 @@ void Tab::update_changed_tree_ui()
|
|
|
|
|
if (!sys_page && modified_page)
|
|
|
|
|
break;
|
|
|
|
|
for (const auto &kvp : group->opt_map()) {
|
|
|
|
|
const std::string& opt_key = kvp.first;
|
|
|
|
|
const std::string &opt_key = kvp.first;
|
|
|
|
|
get_sys_and_mod_flags(opt_key, sys_page, modified_page);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1116,7 +1105,7 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
for (const auto &kvp : group->opt_map()) {
|
|
|
|
|
const std::string& opt_key = kvp.first;
|
|
|
|
|
const std::string &opt_key = kvp.first;
|
|
|
|
|
if ((m_options_list[opt_key] & os) == 0)
|
|
|
|
|
to_sys ? group->back_to_sys_value(opt_key) : group->back_to_initial_value(opt_key);
|
|
|
|
|
}
|
|
|
|
@ -1602,6 +1591,18 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
|
|
|
|
wxGetApp().plater()->on_extruders_change(boost::any_cast<size_t>(value));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (opt_key.find_first_of("nozzle_volume_type") != std::string::npos) {
|
|
|
|
|
int extruder_idx = std::atoi(opt_key.substr(opt_key.find_last_of('#') + 1).c_str());
|
|
|
|
|
for (auto tab : wxGetApp().tabs_list) {
|
|
|
|
|
tab->update_extruder_variants(extruder_idx);
|
|
|
|
|
tab->reload_config();
|
|
|
|
|
}
|
|
|
|
|
for (auto tab : wxGetApp().model_tabs_list) {
|
|
|
|
|
tab->update_extruder_variants(extruder_idx);
|
|
|
|
|
tab->reload_config();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_postpone_update_ui) {
|
|
|
|
|
// It means that not all values are rolled to the system/last saved values jet.
|
|
|
|
|
// And call of the update() can causes a redundant check of the config values,
|
|
|
|
@ -2058,51 +2059,51 @@ void TabPrint::build()
|
|
|
|
|
|
|
|
|
|
page = add_options_page(L("Speed"), "empty");
|
|
|
|
|
optgroup = page->new_optgroup(L("Initial layer speed"), L"param_speed_first", 15);
|
|
|
|
|
optgroup->append_single_option_line("initial_layer_speed");
|
|
|
|
|
optgroup->append_single_option_line("initial_layer_infill_speed");
|
|
|
|
|
optgroup->append_single_option_line("initial_layer_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("initial_layer_infill_speed", "", 0);
|
|
|
|
|
optgroup = page->new_optgroup(L("Other layers speed"), L"param_speed", 15);
|
|
|
|
|
optgroup->append_single_option_line("outer_wall_speed");
|
|
|
|
|
optgroup->append_single_option_line("inner_wall_speed");
|
|
|
|
|
optgroup->append_single_option_line("small_perimeter_speed");
|
|
|
|
|
optgroup->append_single_option_line("small_perimeter_threshold");
|
|
|
|
|
optgroup->append_single_option_line("sparse_infill_speed");
|
|
|
|
|
optgroup->append_single_option_line("internal_solid_infill_speed");
|
|
|
|
|
optgroup->append_single_option_line("top_surface_speed");
|
|
|
|
|
optgroup->append_single_option_line("enable_overhang_speed", "slow-down-for-overhang");
|
|
|
|
|
optgroup->append_single_option_line("outer_wall_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("inner_wall_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("small_perimeter_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("small_perimeter_threshold", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("sparse_infill_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("internal_solid_infill_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("top_surface_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("enable_overhang_speed", "slow-down-for-overhang", 0);
|
|
|
|
|
Line line = { L("Overhang speed"), L("This is the speed for various overhang degrees. Overhang degrees are expressed as a percentage of line width. 0 speed means no slowing down for the overhang degree range and wall speed is used") };
|
|
|
|
|
line.label_path = "slow-down-for-overhang";
|
|
|
|
|
line.append_option(optgroup->get_option("overhang_1_4_speed"));
|
|
|
|
|
line.append_option(optgroup->get_option("overhang_2_4_speed"));
|
|
|
|
|
line.append_option(optgroup->get_option("overhang_3_4_speed"));
|
|
|
|
|
line.append_option(optgroup->get_option("overhang_4_4_speed"));
|
|
|
|
|
line.append_option(optgroup->get_option("overhang_1_4_speed", 0));
|
|
|
|
|
line.append_option(optgroup->get_option("overhang_2_4_speed", 0));
|
|
|
|
|
line.append_option(optgroup->get_option("overhang_3_4_speed", 0));
|
|
|
|
|
line.append_option(optgroup->get_option("overhang_4_4_speed", 0));
|
|
|
|
|
optgroup->append_line(line);
|
|
|
|
|
optgroup->append_single_option_line("overhang_totally_speed");
|
|
|
|
|
optgroup->append_single_option_line("bridge_speed");
|
|
|
|
|
optgroup->append_single_option_line("gap_infill_speed");
|
|
|
|
|
optgroup->append_single_option_line("support_speed");
|
|
|
|
|
optgroup->append_single_option_line("support_interface_speed");
|
|
|
|
|
optgroup->append_single_option_line("overhang_totally_speed", 0);
|
|
|
|
|
optgroup->append_single_option_line("bridge_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("gap_infill_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("support_speed", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("support_interface_speed", "", 0);
|
|
|
|
|
|
|
|
|
|
optgroup = page->new_optgroup(L("Travel speed"), L"param_travel_speed", 15);
|
|
|
|
|
optgroup->append_single_option_line("travel_speed");
|
|
|
|
|
optgroup->append_single_option_line("travel_speed", "", 0);
|
|
|
|
|
|
|
|
|
|
optgroup = page->new_optgroup(L("Acceleration"), L"param_acceleration", 15);
|
|
|
|
|
optgroup->append_single_option_line("default_acceleration");
|
|
|
|
|
optgroup->append_single_option_line("initial_layer_acceleration");
|
|
|
|
|
optgroup->append_single_option_line("outer_wall_acceleration");
|
|
|
|
|
optgroup->append_single_option_line("inner_wall_acceleration");
|
|
|
|
|
optgroup->append_single_option_line("top_surface_acceleration");
|
|
|
|
|
optgroup->append_single_option_line("sparse_infill_acceleration");
|
|
|
|
|
optgroup->append_single_option_line("accel_to_decel_enable");
|
|
|
|
|
optgroup->append_single_option_line("accel_to_decel_factor");
|
|
|
|
|
optgroup->append_single_option_line("default_acceleration", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("initial_layer_acceleration", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("outer_wall_acceleration", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("inner_wall_acceleration", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("top_surface_acceleration", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("sparse_infill_acceleration", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("accel_to_decel_enable", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("accel_to_decel_factor", "", 0);
|
|
|
|
|
|
|
|
|
|
optgroup = page->new_optgroup(L("Jerk(XY)"), L"param_acceleration", 15);
|
|
|
|
|
optgroup->append_single_option_line("default_jerk");
|
|
|
|
|
optgroup->append_single_option_line("outer_wall_jerk");
|
|
|
|
|
optgroup->append_single_option_line("inner_wall_jerk");
|
|
|
|
|
optgroup->append_single_option_line("infill_jerk");
|
|
|
|
|
optgroup->append_single_option_line("top_surface_jerk");
|
|
|
|
|
optgroup->append_single_option_line("initial_layer_jerk");
|
|
|
|
|
optgroup->append_single_option_line("travel_jerk");
|
|
|
|
|
optgroup->append_single_option_line("default_jerk", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("outer_wall_jerk", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("inner_wall_jerk", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("infill_jerk", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("top_surface_jerk", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("initial_layer_jerk", "", 0);
|
|
|
|
|
optgroup->append_single_option_line("travel_jerk", "", 0);
|
|
|
|
|
|
|
|
|
|
#ifdef HAS_PRESSURE_EQUALIZER
|
|
|
|
|
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive");
|
|
|
|
@ -2345,7 +2346,6 @@ void TabPrint::clear_pages()
|
|
|
|
|
m_top_bottom_shell_thickness_explanation = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//BBS: GUI refactor
|
|
|
|
|
|
|
|
|
|
static std::vector<std::string> intersect(std::vector<std::string> const& l, std::vector<std::string> const& r)
|
|
|
|
@ -3964,6 +3964,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
|
|
|
|
|
// load_config(new_conf);
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
update_dirty();
|
|
|
|
|
on_value_change(opt_key, value);
|
|
|
|
|
update();
|
|
|
|
@ -4333,6 +4334,7 @@ void Tab::load_current_preset()
|
|
|
|
|
update();
|
|
|
|
|
|
|
|
|
|
// Reload preset pages with the new configuration values.
|
|
|
|
|
update_extruder_variants();
|
|
|
|
|
reload_config();
|
|
|
|
|
|
|
|
|
|
update_ui_items_related_on_parent_preset(m_presets->get_selected_preset_parent());
|
|
|
|
@ -5059,6 +5061,8 @@ bool Tab::tree_sel_change_delayed(wxCommandEvent& event)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
m_active_page = page;
|
|
|
|
|
if (m_extruder_switch)
|
|
|
|
|
GetSizer()->Show(m_extruder_switch, !m_active_page->m_opt_id_map.empty());
|
|
|
|
|
|
|
|
|
|
auto throw_if_canceled = std::function<void()>([this](){
|
|
|
|
|
#ifdef WIN32
|
|
|
|
@ -5550,6 +5554,7 @@ void TabPrinter::set_extruder_volume_type(int extruder_id, NozzleVolumeType type
|
|
|
|
|
auto nozzle_volumes = m_config->option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
|
|
|
|
|
assert(nozzle_volumes->values.size() > (size_t)extruder_id);
|
|
|
|
|
nozzle_volumes->values[extruder_id] = type;
|
|
|
|
|
on_value_change((boost::format("nozzle_volume_type#%1%") % extruder_id).str(), int(type));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return a callback to create a TabPrinter widget to edit bed shape
|
|
|
|
@ -5687,6 +5692,88 @@ void Tab::set_just_edit(bool just_edit)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Call from:
|
|
|
|
|
/// 1: on_value_change "nozzle_volume_type"
|
|
|
|
|
/// 2: on_preset_loaded (extruder_id = -1)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="extruder_id"></param>
|
|
|
|
|
|
|
|
|
|
void Tab::update_extruder_variants(int extruder_id)
|
|
|
|
|
{
|
|
|
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << extruder_id;
|
|
|
|
|
if (m_extruder_switch) {
|
|
|
|
|
Preset &printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset();
|
|
|
|
|
auto nozzle_volumes = printer_preset.config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
|
|
|
|
|
if (nozzle_volumes->size() == 2) {
|
|
|
|
|
auto nozzle_volumes_def = printer_preset.config.def()->get("nozzle_volume_type");
|
|
|
|
|
wxString left, right;
|
|
|
|
|
for (size_t i = 0; i < nozzle_volumes_def->enum_labels.size(); ++i) {
|
|
|
|
|
if (nozzle_volumes->values[0] == i) left = _L(nozzle_volumes_def->enum_labels[i]);
|
|
|
|
|
if (nozzle_volumes->values[1] == i) right = _L(nozzle_volumes_def->enum_labels[i]);
|
|
|
|
|
}
|
|
|
|
|
m_extruder_switch->SetLabels(wxString::Format(_L("Left: %s"), left), wxString::Format(_L("Right: %s"), right));
|
|
|
|
|
m_extruder_switch->SetValue(extruder_id == 1);
|
|
|
|
|
} else {
|
|
|
|
|
GetSizer()->Show(m_extruder_switch, false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
switch_excluder(extruder_id);
|
|
|
|
|
if (m_extruder_switch)
|
|
|
|
|
GetSizer()->Show(m_extruder_switch, m_active_page && !m_active_page->m_opt_id_map.empty());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Tab::switch_excluder(int extruder_id)
|
|
|
|
|
{
|
|
|
|
|
Preset & printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset();
|
|
|
|
|
auto nozzle_volumes = printer_preset.config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
|
|
|
|
|
auto extruders = printer_preset.config.option<ConfigOptionEnumsGeneric>("extruder_type");
|
|
|
|
|
std::pair<std::string, std::string> variant_keys[]{
|
|
|
|
|
{}, {"print_extruder_id", "print_extruder_variant"}, // Preset::TYPE_PRINT
|
|
|
|
|
{}, {"", "filament_extruder_variant"}, // Preset::TYPE_FILAMENT filament don't use id anymore
|
|
|
|
|
{}, {"printer_extruder_id", "printer_extruder_variant"}, // Preset::TYPE_PRINTER
|
|
|
|
|
};
|
|
|
|
|
if (m_extruder_switch) {
|
|
|
|
|
int current_extruder = m_extruder_switch->GetValue() ? 1 : 0;
|
|
|
|
|
if (extruder_id == -1)
|
|
|
|
|
extruder_id = current_extruder;
|
|
|
|
|
else if (extruder_id != current_extruder)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
auto get_index_for_extruder =
|
|
|
|
|
[this, &extruders, &nozzle_volumes, variant_keys = variant_keys[m_type >= Preset::TYPE_COUNT ? Preset::TYPE_PRINT : m_type]](int extruder_id) {
|
|
|
|
|
return m_config->get_index_for_extruder(extruder_id + 1, variant_keys.first,
|
|
|
|
|
ExtruderType(extruders->values[extruder_id]), NozzleVolumeType(nozzle_volumes->values[extruder_id]), variant_keys.second);
|
|
|
|
|
};
|
|
|
|
|
auto index = get_index_for_extruder(extruder_id == -1 ? 0 : extruder_id);
|
|
|
|
|
for (auto page : m_pages) {
|
|
|
|
|
bool is_extruder = false;
|
|
|
|
|
page->m_opt_id_map.clear();
|
|
|
|
|
if (m_extruder_switch == nullptr && page->title().StartsWith("Extruder ")) {
|
|
|
|
|
int extruder_id2 = std::atoi(page->title().Mid(9).ToUTF8()) - 1;
|
|
|
|
|
if (extruder_id >= 0 && extruder_id2 != extruder_id)
|
|
|
|
|
continue;
|
|
|
|
|
if (extruder_id2 > 0)
|
|
|
|
|
index = get_index_for_extruder(extruder_id2);
|
|
|
|
|
is_extruder = true;
|
|
|
|
|
}
|
|
|
|
|
for (auto group : page->m_optgroups) {
|
|
|
|
|
if (is_extruder && group->title == "Type") {
|
|
|
|
|
for (auto &opt : group->opt_map())
|
|
|
|
|
page->m_opt_id_map.insert({opt.first, opt.first});
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
for (auto &opt : group->opt_map()) {
|
|
|
|
|
if (opt.second.second >= 0) {
|
|
|
|
|
const_cast<int &>(opt.second.second) = index;
|
|
|
|
|
page->m_opt_id_map.insert({opt.second.first + "#" + std::to_string(index), opt.first});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Tab::compatible_widget_reload(PresetDependencies &deps)
|
|
|
|
|
{
|
|
|
|
|
Field* field = this->get_field(deps.key_condition);
|
|
|
|
|