Merge branch 'master' into lm_tm_hollowing

This commit is contained in:
Lukas Matena 2019-12-12 11:37:33 +01:00
commit 537260494d
185 changed files with 83280 additions and 4591 deletions
src/slic3r/GUI

View file

@ -59,6 +59,11 @@ static PrinterTechnology printer_technology()
return wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology();
}
static const Selection& scene_selection()
{
return wxGetApp().plater()->canvas3D()->get_selection();
}
// Config from current edited printer preset
static DynamicPrintConfig& printer_config()
{
@ -329,7 +334,7 @@ wxString ObjectList::get_mesh_errors_list(const int obj_idx, const int vol_idx /
return ""; // hide tooltip
// Create tooltip string, if there are errors
wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):\n")), errors);
wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):")), errors) + "\n";
const stl_stats& stats = vol_idx == -1 ?
(*m_objects)[obj_idx]->get_object_stl_stats() :
@ -526,6 +531,8 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item)
if (!m_config)
return;
take_snapshot(_(L("Change Extruder")));
const int extruder = m_objects_model->GetExtruderNumber(item);
m_config->set_key_value("extruder", new ConfigOptionInt(extruder));
@ -806,7 +813,7 @@ void ObjectList::list_manipulation(bool evt_context_menu/* = false*/)
if (!item) {
if (col == nullptr) {
if (wxOSX)
if (wxOSX && !multiple_selection())
UnselectAll();
else if (!evt_context_menu)
// Case, when last item was deleted and under GTK was called wxEVT_DATAVIEW_SELECTION_CHANGED,
@ -821,8 +828,13 @@ void ObjectList::list_manipulation(bool evt_context_menu/* = false*/)
}
if (wxOSX && item && col) {
wxDataViewItemArray sels;
GetSelections(sels);
UnselectAll();
Select(item);
if (sels.Count() > 1)
SetSelections(sels);
else
Select(item);
}
const wxString title = col->GetTitle();
@ -896,10 +908,6 @@ void ObjectList::extruder_editing()
if (!item || !(m_objects_model->GetItemType(item) & (itVolume | itObject)))
return;
std::vector<wxBitmap*> icons = get_extruder_color_icons();
if (icons.empty())
return;
const int column_width = GetColumn(colExtruder)->GetWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X) + 5;
wxPoint pos = get_mouse_position_in_control();
@ -907,29 +915,10 @@ void ObjectList::extruder_editing()
pos.x = GetColumn(colName)->GetWidth() + GetColumn(colPrint)->GetWidth() + 5;
pos.y -= GetTextExtent("m").y;
if (!m_extruder_editor)
m_extruder_editor = new wxBitmapComboBox(this, wxID_ANY, wxEmptyString, pos, size,
0, nullptr, wxCB_READONLY);
else
{
m_extruder_editor->SetPosition(pos);
m_extruder_editor->SetMinSize(size);
m_extruder_editor->SetSize(size);
m_extruder_editor->Clear();
m_extruder_editor->Show();
}
apply_extruder_selector(&m_extruder_editor, this, L("default"), pos, size);
int i = 0;
for (wxBitmap* bmp : icons) {
if (i == 0) {
m_extruder_editor->Append(_(L("default")), *bmp);
++i;
}
m_extruder_editor->Append(wxString::Format("%d", i), *bmp);
++i;
}
m_extruder_editor->SetSelection(m_objects_model->GetExtruderNumber(item));
m_extruder_editor->Show();
auto set_extruder = [this]()
{
@ -941,6 +930,7 @@ void ObjectList::extruder_editing()
m_objects_model->SetExtruder(m_extruder_editor->GetString(selection), item);
m_extruder_editor->Hide();
update_extruder_in_config(item);
};
// to avoid event propagation to other sidebar items
@ -949,13 +939,6 @@ void ObjectList::extruder_editing()
set_extruder();
evt.StopPropagation();
});
/*
m_extruder_editor->Bind(wxEVT_KILL_FOCUS, [set_extruder](wxFocusEvent& evt)
{
set_extruder();
evt.Skip();
});*/
}
void ObjectList::copy()
@ -1335,7 +1318,10 @@ void ObjectList::get_settings_choice(const wxString& category_name)
void ObjectList::get_freq_settings_choice(const wxString& bundle_name)
{
std::vector<std::string> options = get_options_for_bundle(bundle_name);
wxDataViewItem item = GetSelection();
const Selection& selection = scene_selection();
wxDataViewItem item = GetSelectedItemsCount() > 1 && selection.is_single_full_object() ?
m_objects_model->GetItemById(selection.get_object_idx()) :
GetSelection();
ItemType item_type = m_objects_model->GetItemType(item);
@ -1423,17 +1409,23 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
const ConfigOptionMode mode = wxGetApp().get_mode();
wxWindow* parent = wxGetApp().plater();
if (mode == comAdvanced) {
append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)].first), "",
[this](wxCommandEvent&) { load_subobject(ModelVolumeType::MODEL_PART); }, ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)].second);
[this](wxCommandEvent&) { load_subobject(ModelVolumeType::MODEL_PART); },
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)].second, nullptr,
[this]() { return is_instance_or_object_selected(); }, parent);
}
if (mode == comSimple) {
append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_ENFORCER)].first), "",
[this](wxCommandEvent&) { load_generic_subobject(L("Box"), ModelVolumeType::SUPPORT_ENFORCER); },
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_ENFORCER)].second);
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_ENFORCER)].second, nullptr,
[this]() { return is_instance_or_object_selected(); }, parent);
append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER)].first), "",
[this](wxCommandEvent&) { load_generic_subobject(L("Box"), ModelVolumeType::SUPPORT_BLOCKER); },
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER)].second);
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER)].second, nullptr,
[this]() { return is_instance_or_object_selected(); }, parent);
return;
}
@ -1443,7 +1435,8 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
auto& item = ADD_VOLUME_MENU_ITEMS[type];
wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType(type));
append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second);
append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second,
[this]() { return is_instance_or_object_selected(); }, parent);
}
}
@ -1454,10 +1447,17 @@ wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu)
[this]() { return is_splittable(); }, wxGetApp().plater());
}
wxMenuItem* ObjectList::append_menu_item_layers_editing(wxMenu* menu)
bool ObjectList::is_instance_or_object_selected()
{
const Selection& selection = scene_selection();
return selection.is_single_full_instance() || selection.is_single_full_object();
}
wxMenuItem* ObjectList::append_menu_item_layers_editing(wxMenu* menu, wxWindow* parent)
{
return append_menu_item(menu, wxID_ANY, _(L("Height range Modifier")), "",
[this](wxCommandEvent&) { layers_editing(); }, "edit_layers_all", menu);
[this](wxCommandEvent&) { layers_editing(); }, "edit_layers_all", menu,
[this]() { return is_instance_or_object_selected(); }, parent);
}
wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
@ -1498,6 +1498,12 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
#endif
menu->DestroySeparators(); // delete old separators
// If there are selected more then one instance but not all of them
// don't add settings menu items
const Selection& selection = scene_selection();
if (selection.is_multiple_full_instance() && !selection.is_single_full_object())
return nullptr;
const auto sel_vol = get_selected_model_volume();
if (sel_vol && sel_vol->type() >= ModelVolumeType::SUPPORT_ENFORCER)
return nullptr;
@ -1513,7 +1519,8 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
menu->SetFirstSeparator();
// Add frequently settings
const bool is_object_settings = m_objects_model->GetItemType(GetSelection()) == itObject;
const ItemType item_type = m_objects_model->GetItemType(GetSelection());
const bool is_object_settings = item_type & itObject || item_type & itInstance || selection.is_single_full_object();
create_freq_settings_popupmenu(menu, is_object_settings);
if (mode == comAdvanced)
@ -1539,15 +1546,35 @@ wxMenuItem* ObjectList::append_menu_item_change_type(wxMenu* menu)
wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu, wxWindow* parent)
{
return append_menu_item(menu, wxID_ANY, _(L("Set as a Separated Object")), "",
wxMenuItem* menu_item = append_menu_item(menu, wxID_ANY, _(L("Set as a Separated Object")), "",
[this](wxCommandEvent&) { split_instances(); }, "", menu, [](){return wxGetApp().plater()->can_set_instance_to_object(); }, parent);
/* New behavior logic:
* 1. Split Object to several separated object, if ALL instances are selected
* 2. Separate selected instances from the initial object to the separated object,
* if some (not all) instances are selected
*/
parent->Bind(wxEVT_UPDATE_UI, [](wxUpdateUIEvent& evt) {
evt.SetText(wxGetApp().plater()->canvas3D()->get_selection().is_single_full_object() ?
_(L("Set as a Separated Objects")) : _(L("Set as a Separated Object")));
}, menu_item->GetId());
return menu_item;
}
wxMenuItem* ObjectList::append_menu_item_printable(wxMenu* menu, wxWindow* /*parent*/)
{
return append_menu_check_item(menu, wxID_ANY, _(L("Printable")), "", [](wxCommandEvent&) {
wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state();
}, menu);
return append_menu_check_item(menu, wxID_ANY, _(L("Printable")), "", [this](wxCommandEvent&) {
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
wxDataViewItem item;
if (GetSelectedItemsCount() > 1 && selection.is_single_full_object())
item = m_objects_model->GetItemById(selection.get_object_idx());
else
item = GetSelection();
if (item)
toggle_printable_state(item);
}, menu);
}
void ObjectList::append_menu_items_osx(wxMenu* menu)
@ -1643,7 +1670,7 @@ void ObjectList::create_object_popupmenu(wxMenu *menu)
menu->AppendSeparator();
// Layers Editing for object
append_menu_item_layers_editing(menu);
append_menu_item_layers_editing(menu, wxGetApp().plater());
menu->AppendSeparator();
// rest of a object_menu will be added later in:
@ -1687,17 +1714,6 @@ void ObjectList::create_part_popupmenu(wxMenu *menu)
void ObjectList::create_instance_popupmenu(wxMenu*menu)
{
m_menu_item_split_instances = append_menu_item_instance_to_object(menu, wxGetApp().plater());
/* New behavior logic:
* 1. Split Object to several separated object, if ALL instances are selected
* 2. Separate selected instances from the initial object to the separated object,
* if some (not all) instances are selected
*/
wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [](wxUpdateUIEvent& evt) {
// evt.Enable(can_split_instances()); }, m_menu_item_split_instances->GetId());
evt.SetText(wxGetApp().plater()->canvas3D()->get_selection().is_single_full_object() ?
_(L("Set as a Separated Objects")) : _(L("Set as a Separated Object")));
}, m_menu_item_split_instances->GetId());
}
void ObjectList::create_default_popupmenu(wxMenu*menu)
@ -1711,7 +1727,7 @@ wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu)
wxMenu *menu = new wxMenu;
settings_menu_hierarchy settings_menu;
const bool is_part = m_objects_model->GetParent(GetSelection()) != wxDataViewItem(nullptr);
const bool is_part = !(m_objects_model->GetItemType(GetSelection()) == itObject || scene_selection().is_single_full_object());
get_options_menu(settings_menu, is_part);
for (auto cat : settings_menu) {
@ -1880,7 +1896,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
if (obj_idx < 0)
return;
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
const Selection& selection = scene_selection();
assert(obj_idx == selection.get_object_idx());
/** Any changes of the Object's composition is duplicated for all Object's Instances
@ -2205,9 +2221,13 @@ void ObjectList::split()
void ObjectList::layers_editing()
{
const auto item = GetSelection();
const int obj_idx = get_selected_obj_idx();
if (!item || obj_idx < 0)
const Selection& selection = scene_selection();
const int obj_idx = selection.get_object_idx();
wxDataViewItem item = obj_idx >= 0 && GetSelectedItemsCount() > 1 && selection.is_single_full_object() ?
m_objects_model->GetItemById(obj_idx) :
GetSelection();
if (!item)
return;
const wxDataViewItem obj_item = m_objects_model->GetTopParent(item);
@ -2320,7 +2340,7 @@ bool ObjectList::selected_instances_of_same_object()
bool ObjectList::can_split_instances()
{
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
const Selection& selection = scene_selection();
return selection.is_multiple_full_instance() || selection.is_single_full_instance();
}
@ -2348,7 +2368,7 @@ void ObjectList::part_selection_changed()
{
og_name = _(L("Group manipulation"));
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
const Selection& selection = scene_selection();
// don't show manipulation panel for case of all Object's parts selection
update_and_show_manipulations = !selection.is_single_full_instance();
}
@ -2956,7 +2976,7 @@ int ObjectList::get_selected_layers_range_idx() const
void ObjectList::update_selections()
{
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
const Selection& selection = scene_selection();
wxDataViewItemArray sels;
if ( ( m_selection_mode & (smSettings|smLayer|smLayerRoot) ) == 0)
@ -3663,7 +3683,7 @@ void ObjectList::instances_to_separated_objects(const int obj_idx)
void ObjectList::split_instances()
{
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
const Selection& selection = scene_selection();
const int obj_idx = selection.get_object_idx();
if (obj_idx == -1)
return;
@ -3876,6 +3896,9 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const
wxDataViewItemArray sels;
GetSelections(sels);
if (!sels.empty())
take_snapshot(_(L("Change Extruders")));
for (const wxDataViewItem& item : sels)
{
DynamicPrintConfig& config = get_item_config(item);