Fix + Support 'Default' filament option (index 0) (#13887)

* Support 'Default' filament option (index 0)

Treat filament index 0 as the new "Default" (use active object/part filament) instead of using 1. Update config defaults and tooltips for wall/sparse/solid infill filament options (min/default -> 0, tooltip explains "Default"). Adjust normalization and propagation logic to respect explicit feature overrides and only apply base extruder when feature values are zero; only copy sparse->solid infill when sparse > 0. Introduce FeatureFilamentOverrideMask and clamp_feature_filament_to_valid to resolve and clamp feature filaments. Update UI lists and selection behavior to expose a "Default" entry and handle zero-based indices in PartPlate and Plater.

* enable_filament_for_features option

Co-Authored-By: LixNix <105106115+lixnix@users.noreply.github.com>

* \n

* Allow wipe_tower_filament to equal nozzle count

Relax the assertion in Print::extruders to permit wipe_tower_filament == config().nozzle_diameter.size(). The configuration value is 1-based and the code subtracts 1 when pushing the extruder index, so equality should be valid and selecting the last nozzle should not trigger an assertion.

* Revert "Allow wipe_tower_filament to equal nozzle count"

This reverts commit 2c976574327a8bcdc74a1b296bf1aaff7752a94e.

* Revert "enable_filament_for_features option"

This reverts commit 01c13baeddb8e26793f752deab788ee4d086975b.

* Migrate legacy feature filament defaults

Add migration logic to convert legacy feature filament selections from 1 to 0 for older 3mf files. Introduces a local migrate_legacy_feature_filament_defaults lambda in src/OrcaSlicer.cpp and src/slic3r/GUI/Plater.cpp that scans keys (wall_filament, sparse_infill_filament, solid_infill_filament, support_filament, support_interface_filament) on configs/objects/volumes, updates values, counts conversions and logs the result. Also adds a Semver check for "2.4.0-dev" in OrcaSlicer to trigger the migration for files older than that version. This preserves expected default filament selections when loading older project files.

* Update OrcaSlicer.cpp

* Extract migration helper to ConfigMigrations

Centralize legacy feature-filament default migration by moving the duplicated lambda into ConfigMigrations::migrate_legacy_feature_filament_defaults (src/libslic3r/Config.cpp) and declaring it in Config.hpp. Update OrcaSlicer.cpp and slic3r/GUI/Plater.cpp to call the new function instead of inline lambdas. The helper converts specific feature filament keys (wall_filament, sparse_infill_filament, solid_infill_filament, support_filament, support_interface_filament) from int 1 to 0 and returns the count of conversions to avoid duplicated migration logic.

* Remove DynamicFilamentList1Based and consolidate lists

Delete the specialized DynamicFilamentList1Based struct and its global instance. Update Choice registrations to use the single dynamic_filament_list for wall, sparse_infill and solid_infill filaments, and remove the extra update call for the removed instance. This consolidates filament choice handling and removes duplicated logic in Plater.cpp.

* move it

* fix objects

* Update Config.hpp

* Update profiles
This commit is contained in:
Ian Bassi
2026-05-28 23:54:26 -03:00
committed by GitHub
parent d3b110ebf6
commit 3db37d004a
95 changed files with 433 additions and 386 deletions

View File

@@ -876,54 +876,6 @@ struct DynamicFilamentList : DynamicList
}
};
struct DynamicFilamentList1Based : DynamicFilamentList
{
void apply_on(Choice *c) override
{
if (items.empty())
update(true);
auto cb = dynamic_cast<ComboBox *>(c->window);
auto n = cb->GetSelection();
cb->Clear();
for (auto i : items) {
cb->Append(i.first, *i.second);
}
if (n < cb->GetCount())
cb->SetSelection(n);
}
wxString get_value(int index) override
{
wxString str;
str << index+1;
return str;
}
int index_of(wxString value) override
{
long n = 0;
if(!value.ToLong(&n))
return -1;
--n;
return (n >= 0 && n <= items.size()) ? int(n) : -1;
}
void update(bool force = false)
{
items.clear();
if (!force && m_choices.empty())
return;
auto icons = get_extruder_color_icons(true);
auto presets = wxGetApp().preset_bundle->filament_presets;
for (int i = 0; i < presets.size(); ++i) {
wxString str;
std::string type;
wxGetApp().preset_bundle->filaments.find_preset(presets[i])->get_filament_type(type);
str << type;
items.push_back({str, i < icons.size() ? icons[i] : nullptr});
}
DynamicList::update();
}
};
// Check if the machine supports Junction Deviation (Marlin firmware with machine_max_junction_deviation > 0)
static bool has_junction_deviation(const DynamicPrintConfig* printer_config)
{
@@ -940,7 +892,6 @@ static bool has_junction_deviation(const DynamicPrintConfig* printer_config)
}
static DynamicFilamentList dynamic_filament_list;
static DynamicFilamentList1Based dynamic_filament_list_1_based;
class AMSCountPopupWindow : public PopupWindow
{
@@ -1647,9 +1598,9 @@ Sidebar::Sidebar(Plater *parent)
{
Choice::register_dynamic_list("support_filament", &dynamic_filament_list);
Choice::register_dynamic_list("support_interface_filament", &dynamic_filament_list);
Choice::register_dynamic_list("wall_filament", &dynamic_filament_list_1_based);
Choice::register_dynamic_list("sparse_infill_filament", &dynamic_filament_list_1_based);
Choice::register_dynamic_list("solid_infill_filament", &dynamic_filament_list_1_based);
Choice::register_dynamic_list("wall_filament", &dynamic_filament_list);
Choice::register_dynamic_list("sparse_infill_filament", &dynamic_filament_list);
Choice::register_dynamic_list("solid_infill_filament", &dynamic_filament_list);
Choice::register_dynamic_list("wipe_tower_filament", &dynamic_filament_list);
p->scrolled = new wxPanel(this);
@@ -3767,7 +3718,6 @@ void Sidebar::show_SEMM_buttons()
void Sidebar::update_dynamic_filament_list()
{
dynamic_filament_list.update();
dynamic_filament_list_1_based.update();
}
PlaterPresetComboBox* Sidebar::printer_combox()
@@ -6203,6 +6153,23 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
}
}
if (load_config && !config_loaded.empty() &&
(en_3mf_file_type == En3mfType::From_BBS || en_3mf_file_type == En3mfType::From_Orca) &&
file_version < Semver("2.4.0-dev")) {
int converted_count = ConfigMigrations::migrate_legacy_feature_filament_defaults(config_loaded);
for (ModelObject *model_object : model.objects) {
converted_count += ConfigMigrations::migrate_legacy_feature_filament_defaults(model_object->config);
for (ModelVolume *model_volume : model_object->volumes)
converted_count += ConfigMigrations::migrate_legacy_feature_filament_defaults(model_volume->config);
}
if (converted_count > 0) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << " "
<< boost::format("old 3mf version %1%, migrated %2% feature filament selections from 1 to 0 (Default)")
% file_version.to_string() % converted_count;
}
}
// plate data
if (plate_data.size() > 0) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", import 3mf UPDATE_GCODE_RESULT \n");