mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-26 10:21:00 +00:00
Update from FS at b3c41fda4.
Slicing
- align merge_segmented_layers shape with FS apply_mm_segmentation
(size = num_facets_states, loop from 0, no -1 shift); painted mixed
regions were previously attributed to filament_id-1 of intent.
apply_fuzzy_skin_segmentation reads channel 1;
apply_mixed_surface_indentation uses segmentation_channel_filament_id
- port apply_mixed_surface_indentation, apply_mixed_component_surface_offsets,
apply_mixed_region_surface_offsets, apply_surface_emboss_mixed_region_override,
plus surface_emboss_mixed_* debug subsystem
- refactor apply_mm_segmentation (by-value MM, bias_mode, surface-type-
preserving intersection, region normalization, post-MM dump); hoist MM
segmentation into slice_volumes so mixed apply_* flow can mutate it
- restore clear_local_z_plan() invalidation hooks
(PrintObject.cpp:805/1264/1286)
GCode
- add LayerTools::preserve_extruder_order, honored by collect_extruders,
both reorder_extruders overloads, and
reorder_filaments_for_minimum_flush_volume; helpers
append_unique_preserve_order / remove_duplicates_preserve_order
- wire MixedFilamentManager::ordered_perimeter_extruders for grouped
manual-pattern walls; set preserve_extruder_order when >= 2
- mixed-aware support: layer_height set for support-only layers,
ExtrusionRole-based has_support/has_interface with erMixed short-
circuit, support_filament / support_interface_filament routed through
resolve_mixed
Print
- materialize mixed_filament_pointillism_{pixel_size,line_gap} in
PrintApply's option-tracking block so in-session edits diff correctly
GUI
- Tab::on_value_change: dithering_local_z_mode cascading clears, 17-key
project_config sync, update_mixed_filament_panel(false) on
mixed_filament_component_bias_enabled change
- GUI_Factories: physical_filaments_count, ui_ordered_filament_ids,
filament_menu_item_name; filaments_count includes enabled mixed
virtuals; right-click 'Change filament' submenus iterate UI-ordered IDs
Tests
- sentinel asserting MultiMaterialSegmentation uses FS-aligned shape
(39 -> 40)
This commit is contained in:
@@ -35,9 +35,48 @@ static PrinterTechnology printer_technology()
|
||||
return wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology();
|
||||
}
|
||||
|
||||
static int physical_filaments_count()
|
||||
{
|
||||
return std::max(wxGetApp().filaments_cnt(), 0);
|
||||
}
|
||||
|
||||
static int filaments_count()
|
||||
{
|
||||
return wxGetApp().filaments_cnt();
|
||||
if (wxGetApp().preset_bundle == nullptr)
|
||||
return 0;
|
||||
const int physical = physical_filaments_count();
|
||||
const auto &mixed_mgr = wxGetApp().preset_bundle->mixed_filaments;
|
||||
return static_cast<int>(mixed_mgr.total_filaments(size_t(physical)));
|
||||
}
|
||||
|
||||
static std::vector<unsigned int> ui_ordered_filament_ids()
|
||||
{
|
||||
if (wxGetApp().plater() == nullptr)
|
||||
return {};
|
||||
return wxGetApp().plater()->sidebar().get_ui_ordered_filament_ids();
|
||||
}
|
||||
|
||||
static wxString filament_menu_item_name(const int filament_id_1based, const int display_filament_id_1based)
|
||||
{
|
||||
if (filament_id_1based <= 0)
|
||||
return _L("Default");
|
||||
|
||||
if (wxGetApp().preset_bundle == nullptr)
|
||||
return wxString::Format(_L("Filament %d"), filament_id_1based);
|
||||
|
||||
const int physical = physical_filaments_count();
|
||||
if (filament_id_1based <= physical) {
|
||||
const size_t preset_idx = size_t(filament_id_1based - 1);
|
||||
const auto &filament_presets = wxGetApp().preset_bundle->filament_presets;
|
||||
if (preset_idx < filament_presets.size()) {
|
||||
auto preset = wxGetApp().preset_bundle->filaments.find_preset(filament_presets[preset_idx]);
|
||||
if (preset != nullptr)
|
||||
return from_u8(preset->label(false));
|
||||
}
|
||||
return wxString::Format(_L("Filament %d"), filament_id_1based);
|
||||
}
|
||||
|
||||
return wxString::Format(_L("Mixed Filament %d"), display_filament_id_1based);
|
||||
}
|
||||
|
||||
static bool is_improper_category(const std::string& category, const int filaments_cnt, const bool is_object_settings = true)
|
||||
@@ -1042,8 +1081,9 @@ void MenuFactory::append_menu_item_change_extruder(wxMenu* menu)
|
||||
menu->Destroy(item_id);
|
||||
}
|
||||
|
||||
const int filaments_cnt = filaments_count();
|
||||
if (filaments_cnt <= 1)
|
||||
// Use UI-ordered filament IDs (physical first, then enabled mixed in UI order)
|
||||
const std::vector<unsigned int> ordered_filament_ids = ui_ordered_filament_ids();
|
||||
if (ordered_filament_ids.size() <= 1)
|
||||
return;
|
||||
|
||||
wxDataViewItemArray sels;
|
||||
@@ -1059,24 +1099,16 @@ void MenuFactory::append_menu_item_change_extruder(wxMenu* menu)
|
||||
if (sels.Count() == 1) {
|
||||
const ModelConfig& config = obj_list()->get_item_config(sels[0]);
|
||||
// BBS: set default extruder to 1
|
||||
initial_extruder = config.has("extruder") ? config.extruder() : 1;
|
||||
initial_extruder = config.has("extruder") ? config.extruder() : 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= filaments_cnt; i++)
|
||||
for (size_t display_idx = 0; display_idx <= ordered_filament_ids.size(); ++display_idx)
|
||||
{
|
||||
bool is_active_extruder = i == initial_extruder;
|
||||
int icon_idx = i == 0 ? 0 : i - 1;
|
||||
const int actual_filament_id = display_idx == 0 ? 0 : int(ordered_filament_ids[display_idx - 1]);
|
||||
const bool is_active_extruder = actual_filament_id == initial_extruder;
|
||||
const int icon_idx = actual_filament_id == 0 ? 0 : actual_filament_id - 1;
|
||||
|
||||
wxString item_name = _L("Default");
|
||||
|
||||
if (i > 0) {
|
||||
auto preset = wxGetApp().preset_bundle->filaments.find_preset(wxGetApp().preset_bundle->filament_presets[i - 1]);
|
||||
if (preset == nullptr) {
|
||||
item_name = wxString::Format(_L("Filament %d"), i);
|
||||
} else {
|
||||
item_name = from_u8(preset->label(false));
|
||||
}
|
||||
}
|
||||
wxString item_name = filament_menu_item_name(actual_filament_id, int(display_idx));
|
||||
|
||||
if (is_active_extruder) {
|
||||
item_name << " (" + _L("current") + ")";
|
||||
@@ -1084,11 +1116,13 @@ void MenuFactory::append_menu_item_change_extruder(wxMenu* menu)
|
||||
|
||||
if (icon_idx >= 0 && icon_idx < icons.size()) {
|
||||
append_menu_item(
|
||||
extruder_selection_menu, wxID_ANY, item_name, "", [i](wxCommandEvent &) { obj_list()->set_extruder_for_selected_items(i); }, *icons[icon_idx], menu,
|
||||
extruder_selection_menu, wxID_ANY, item_name, "",
|
||||
[actual_filament_id](wxCommandEvent &) { obj_list()->set_extruder_for_selected_items(actual_filament_id); }, *icons[icon_idx], menu,
|
||||
[is_active_extruder]() { return !is_active_extruder; }, m_parent);
|
||||
} else {
|
||||
append_menu_item(
|
||||
extruder_selection_menu, wxID_ANY, item_name, "", [i](wxCommandEvent &) { obj_list()->set_extruder_for_selected_items(i); }, "", menu,
|
||||
extruder_selection_menu, wxID_ANY, item_name, "",
|
||||
[actual_filament_id](wxCommandEvent &) { obj_list()->set_extruder_for_selected_items(actual_filament_id); }, "", menu,
|
||||
[is_active_extruder]() { return !is_active_extruder; }, m_parent);
|
||||
}
|
||||
}
|
||||
@@ -2213,8 +2247,8 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu)
|
||||
menu->Destroy(item_id);
|
||||
}
|
||||
|
||||
int filaments_cnt = filaments_count();
|
||||
if (filaments_cnt <= 1)
|
||||
const std::vector<unsigned int> ordered_filament_ids = ui_ordered_filament_ids();
|
||||
if (ordered_filament_ids.size() <= 1)
|
||||
return;
|
||||
|
||||
wxDataViewItemArray sels;
|
||||
@@ -2229,12 +2263,10 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu)
|
||||
}
|
||||
|
||||
std::vector<wxBitmap*> icons = get_extruder_color_icons(true);
|
||||
if (icons.size() < filaments_cnt) {
|
||||
BOOST_LOG_TRIVIAL(warning) << boost::format("Warning: icons size %1%, filaments_cnt=%2%")%icons.size()%filaments_cnt;
|
||||
if (icons.size() < ordered_filament_ids.size()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << boost::format("Warning: icons size %1%, filaments_cnt=%2%") % icons.size() % ordered_filament_ids.size();
|
||||
if (icons.size() <= 1)
|
||||
return;
|
||||
else
|
||||
filaments_cnt = icons.size();
|
||||
}
|
||||
wxMenu* extruder_selection_menu = new wxMenu();
|
||||
const wxString& name = sels.Count() == 1 ? names[0] : names[1];
|
||||
@@ -2242,47 +2274,27 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu)
|
||||
int initial_extruder = -1; // negative value for multiple object/part selection
|
||||
if (sels.Count() == 1) {
|
||||
const ModelConfig& config = obj_list()->get_item_config(sels[0]);
|
||||
// BBS
|
||||
const auto sel_vol = obj_list()->get_selected_model_volume();
|
||||
if (sel_vol && sel_vol->type() == ModelVolumeType::PARAMETER_MODIFIER)
|
||||
initial_extruder = config.has("extruder") ? config.extruder() : 0;
|
||||
else
|
||||
initial_extruder = config.has("extruder") ? config.extruder() : 1;
|
||||
initial_extruder = config.has("extruder") ? config.extruder() : 0;
|
||||
}
|
||||
|
||||
// BBS
|
||||
bool has_modifier = false;
|
||||
for (auto sel : sels) {
|
||||
if (obj_list()->GetModel()->GetVolumeType(sel) == ModelVolumeType::PARAMETER_MODIFIER) {
|
||||
has_modifier = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = has_modifier ? 0 : 1; i <= filaments_cnt; i++)
|
||||
for (size_t display_idx = 0; display_idx <= ordered_filament_ids.size(); ++display_idx)
|
||||
{
|
||||
// BBS
|
||||
//bool is_active_extruder = i == initial_extruder;
|
||||
const int actual_filament_id = display_idx == 0 ? 0 : int(ordered_filament_ids[display_idx - 1]);
|
||||
bool is_active_extruder = false;
|
||||
|
||||
wxString item_name = _L("Default");
|
||||
|
||||
if (i > 0) {
|
||||
auto preset = wxGetApp().preset_bundle->filaments.find_preset(wxGetApp().preset_bundle->filament_presets[i - 1]);
|
||||
if (preset == nullptr) {
|
||||
item_name = wxString::Format(_L("Filament %d"), i);
|
||||
} else {
|
||||
item_name = from_u8(preset->label(false));
|
||||
}
|
||||
}
|
||||
wxString item_name = filament_menu_item_name(actual_filament_id, int(display_idx));
|
||||
|
||||
if (is_active_extruder) {
|
||||
item_name << " (" + _L("current") + ")";
|
||||
}
|
||||
|
||||
wxBitmap bm = (i == 0 || size_t(i - 1) >= icons.size()) ? wxNullBitmap : *icons[i - 1];
|
||||
append_menu_item(extruder_selection_menu, wxID_ANY, item_name, "",
|
||||
[i](wxCommandEvent&) { obj_list()->set_extruder_for_selected_items(i); }, bm, menu,
|
||||
[actual_filament_id](wxCommandEvent&) { obj_list()->set_extruder_for_selected_items(actual_filament_id); },
|
||||
actual_filament_id == 0 || size_t(actual_filament_id - 1) >= icons.size() ? wxNullBitmap : *icons[size_t(actual_filament_id - 1)], menu,
|
||||
[is_active_extruder]() { return !is_active_extruder; }, m_parent);
|
||||
}
|
||||
menu->Append(wxID_ANY, name, extruder_selection_menu, _L("Change Filament"));
|
||||
|
||||
Reference in New Issue
Block a user