mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 19:01:02 +00:00
Update README and implement dithering features: Change download link in README, add mixed filament management enhancements including filament removal and layer height adjustments for dithering in the MixedFilamentManager. Introduce new configuration options for dithering in the PrintConfig and GUI, and ensure proper handling of mixed filament states during filament deletion.
This commit is contained in:
+10
-2
@@ -108,13 +108,21 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
|
||||
{
|
||||
try{
|
||||
|
||||
if (config.def()->get(opt_key)->type == coBools && config.def()->get(opt_key)->nullable) {
|
||||
const ConfigOptionDef *opt_def = config.def()->get(opt_key);
|
||||
if (opt_def == nullptr)
|
||||
throw Slic3r::RuntimeError("Unknown config option key: " + opt_key);
|
||||
|
||||
// Some older presets may not carry newly introduced keys. Ensure the
|
||||
// option exists before mutating it through typed accessors below.
|
||||
if (!config.has(opt_key))
|
||||
config.set_key_value(opt_key, opt_def->create_default_option());
|
||||
|
||||
if (opt_def->type == coBools && opt_def->nullable) {
|
||||
ConfigOptionBoolsNullable* vec_new = new ConfigOptionBoolsNullable{ boost::any_cast<unsigned char>(value) };
|
||||
config.option<ConfigOptionBoolsNullable>(opt_key)->set_at(vec_new, opt_index, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
const ConfigOptionDef *opt_def = config.def()->get(opt_key);
|
||||
switch (opt_def->type) {
|
||||
case coFloatOrPercent:{
|
||||
std::string str = boost::any_cast<std::string>(value);
|
||||
|
||||
@@ -981,10 +981,29 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
||||
case coPercents:
|
||||
case coFloats:
|
||||
case coFloat:{
|
||||
double val = opt->type == coFloats ?
|
||||
double val = 0.0;
|
||||
if (config.has(opt_key)) {
|
||||
val = opt->type == coFloats ?
|
||||
config.opt_float(opt_key, idx) :
|
||||
opt->type == coFloat ? config.opt_float(opt_key) :
|
||||
config.option<ConfigOptionPercents>(opt_key)->get_at(idx);
|
||||
} else if (opt->default_value) {
|
||||
if (opt->type == coFloats) {
|
||||
const auto *defaults = dynamic_cast<const ConfigOptionFloats*>(opt->default_value.get());
|
||||
if (defaults != nullptr && !defaults->values.empty()) {
|
||||
const size_t safe_idx = std::min(idx, defaults->values.size() - 1);
|
||||
val = defaults->values[safe_idx];
|
||||
}
|
||||
} else if (opt->type == coFloat) {
|
||||
val = opt->default_value->getFloat();
|
||||
} else {
|
||||
const auto *defaults = dynamic_cast<const ConfigOptionPercents*>(opt->default_value.get());
|
||||
if (defaults != nullptr && !defaults->values.empty()) {
|
||||
const size_t safe_idx = std::min(idx, defaults->values.size() - 1);
|
||||
val = defaults->values[safe_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = double_to_string(val);
|
||||
}
|
||||
break;
|
||||
@@ -1009,10 +1028,29 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
||||
ret = from_u8(config.opt_string(opt_key, static_cast<unsigned int>(idx)));
|
||||
break;
|
||||
case coBool:
|
||||
ret = config.opt_bool(opt_key);
|
||||
if (config.has(opt_key)) {
|
||||
ret = config.opt_bool(opt_key);
|
||||
} else if (opt->default_value) {
|
||||
const auto *defaults = dynamic_cast<const ConfigOptionBool*>(opt->default_value.get());
|
||||
ret = defaults != nullptr ? defaults->value : false;
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
break;
|
||||
case coBools:
|
||||
ret = config.opt_bool(opt_key, idx);
|
||||
if (config.has(opt_key)) {
|
||||
ret = config.opt_bool(opt_key, idx);
|
||||
} else if (opt->default_value) {
|
||||
const auto *defaults = dynamic_cast<const ConfigOptionBools*>(opt->default_value.get());
|
||||
if (defaults != nullptr && !defaults->values.empty()) {
|
||||
const size_t safe_idx = std::min(idx, defaults->values.size() - 1);
|
||||
ret = defaults->values[safe_idx];
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
break;
|
||||
case coInt:
|
||||
ret = config.opt_int(opt_key);
|
||||
@@ -1139,10 +1177,27 @@ boost::any ConfigOptionsGroup::get_config_value2(const DynamicPrintConfig& confi
|
||||
ret = config.opt_string(opt_key, static_cast<unsigned int>(idx));
|
||||
break;
|
||||
case coBool:
|
||||
ret = config.opt_bool(opt_key);
|
||||
if (config.has(opt_key))
|
||||
ret = config.opt_bool(opt_key);
|
||||
else if (opt->default_value) {
|
||||
const auto *defaults = dynamic_cast<const ConfigOptionBool*>(opt->default_value.get());
|
||||
ret = defaults != nullptr ? defaults->value : false;
|
||||
} else
|
||||
ret = false;
|
||||
break;
|
||||
case coBools:
|
||||
ret = static_cast<unsigned char>(config.opt_bool(opt_key, idx));
|
||||
if (config.has(opt_key))
|
||||
ret = static_cast<unsigned char>(config.opt_bool(opt_key, idx));
|
||||
else if (opt->default_value) {
|
||||
const auto *defaults = dynamic_cast<const ConfigOptionBools*>(opt->default_value.get());
|
||||
if (defaults != nullptr && !defaults->values.empty()) {
|
||||
const size_t safe_idx = std::min(idx, defaults->values.size() - 1);
|
||||
ret = static_cast<unsigned char>(defaults->values[safe_idx]);
|
||||
} else {
|
||||
ret = static_cast<unsigned char>(false);
|
||||
}
|
||||
} else
|
||||
ret = static_cast<unsigned char>(false);
|
||||
break;
|
||||
case coInt:
|
||||
ret = config.opt_int(opt_key);
|
||||
|
||||
@@ -1436,7 +1436,7 @@ Sidebar::Sidebar(Plater *parent)
|
||||
p->m_sizer_mixed_filaments = new wxBoxSizer(wxVERTICAL);
|
||||
p->m_sizer_mixed_filaments->AddSpacer(FromDIP(4));
|
||||
// Title
|
||||
auto *mixed_title = new wxStaticText(p->m_panel_mixed_filaments, wxID_ANY, _L("Mixed Colors"));
|
||||
auto *mixed_title = new wxStaticText(p->m_panel_mixed_filaments, wxID_ANY, _L("Dithering"));
|
||||
mixed_title->SetFont(Label::Head_14);
|
||||
p->m_sizer_mixed_filaments->Add(mixed_title, 0, wxLEFT | wxRIGHT, FromDIP(16));
|
||||
p->m_sizer_mixed_filaments->AddSpacer(FromDIP(4));
|
||||
@@ -2205,7 +2205,7 @@ void Sidebar::update_mixed_filament_panel()
|
||||
|
||||
// Recreate header.
|
||||
p->m_sizer_mixed_filaments->AddSpacer(FromDIP(4));
|
||||
auto *mixed_title = new wxStaticText(p->m_panel_mixed_filaments, wxID_ANY, _L("Mixed Colors"));
|
||||
auto *mixed_title = new wxStaticText(p->m_panel_mixed_filaments, wxID_ANY, _L("Dithering"));
|
||||
mixed_title->SetFont(Label::Head_14);
|
||||
p->m_sizer_mixed_filaments->Add(mixed_title, 0, wxLEFT | wxRIGHT, FromDIP(16));
|
||||
p->m_sizer_mixed_filaments->AddSpacer(FromDIP(4));
|
||||
@@ -2355,6 +2355,7 @@ void Sidebar::on_filaments_delete(size_t filament_id)
|
||||
p->m_panel_filament_title->Refresh();
|
||||
update_ui_from_settings();
|
||||
dynamic_filament_list.update();
|
||||
update_mixed_filament_panel();
|
||||
}
|
||||
|
||||
void Sidebar::edit_filament() {
|
||||
@@ -14317,10 +14318,40 @@ void Plater::on_filaments_delete(size_t num_filaments, size_t filament_id, int r
|
||||
}*/
|
||||
|
||||
// update mmu info
|
||||
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
|
||||
|
||||
size_t total_filaments = num_filaments;
|
||||
if (preset_bundle != nullptr) {
|
||||
const size_t current_num_physical = preset_bundle->filament_presets.size();
|
||||
total_filaments = preset_bundle->mixed_filaments.total_filaments(current_num_physical);
|
||||
}
|
||||
|
||||
EnforcerBlockerStateMap state_map;
|
||||
for (size_t i = 0; i < state_map.size(); ++i)
|
||||
state_map[i] = EnforcerBlockerType(i);
|
||||
|
||||
const bool can_use_remap = replace_filament_id < 0;
|
||||
static const std::vector<unsigned int> empty_remap;
|
||||
const std::vector<unsigned int> &id_remap =
|
||||
preset_bundle != nullptr ? preset_bundle->last_filament_id_remap() : empty_remap;
|
||||
if (can_use_remap && !id_remap.empty()) {
|
||||
for (size_t i = 1; i < state_map.size(); ++i) {
|
||||
const unsigned int mapped = i < id_remap.size() ? id_remap[i] : 0;
|
||||
if (mapped == 0 || mapped >= state_map.size() || mapped > total_filaments)
|
||||
state_map[i] = EnforcerBlockerType::NONE;
|
||||
else
|
||||
state_map[i] = EnforcerBlockerType(mapped);
|
||||
}
|
||||
}
|
||||
|
||||
for (ModelObject* mo : wxGetApp().model().objects) {
|
||||
for (ModelVolume* mv : mo->volumes) {
|
||||
mv->update_extruder_count_when_delete_filament(num_filaments, filament_id + 1,
|
||||
replace_filament_id + 1); // this function is 1 base
|
||||
if (can_use_remap && !id_remap.empty()) {
|
||||
mv->remap_extruder_ids(total_filaments, state_map);
|
||||
} else {
|
||||
mv->update_extruder_count_when_delete_filament(total_filaments, filament_id + 1,
|
||||
replace_filament_id + 1); // this function is 1 base
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2488,6 +2488,13 @@ optgroup->append_single_option_line("skirt_loops", "others_settings_skirt#loops"
|
||||
|
||||
optgroup->append_single_option_line("timelapse_type", "others_settings_special_mode#timelapse");
|
||||
|
||||
// Use default (no icon) here to avoid runtime bitmap load failures.
|
||||
optgroup = page->new_optgroup(L("Dithering"));
|
||||
optgroup->append_single_option_line("mixed_color_layer_height_a", "others_settings_mixed_colors#layer-height-a");
|
||||
optgroup->append_single_option_line("mixed_color_layer_height_b", "others_settings_mixed_colors#layer-height-b");
|
||||
optgroup->append_single_option_line("dithering_z_step_size", "others_settings_mixed_colors#z-step-size");
|
||||
optgroup->append_single_option_line("dithering_step_painted_zones_only", "others_settings_mixed_colors#painted-zones-only");
|
||||
|
||||
optgroup = page->new_optgroup(L("Fuzzy Skin"), L"fuzzy_skin");
|
||||
optgroup->append_single_option_line("fuzzy_skin", "others_settings_fuzzy_skin");
|
||||
optgroup->append_single_option_line("fuzzy_skin_mode", "others_settings_fuzzy_skin#fuzzy-skin-mode");
|
||||
|
||||
Reference in New Issue
Block a user