Skip to content

Commit

Permalink
Added "Printable" menu item for multiple selection
Browse files Browse the repository at this point in the history
  • Loading branch information
YuSanka committed Mar 24, 2021
1 parent cfcce6f commit 3a53606
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 86 deletions.
63 changes: 37 additions & 26 deletions src/slic3r/GUI/GUI_Factories.cpp
Expand Up @@ -50,7 +50,7 @@ static SettingsFactory::Bundle FREQ_SETTINGS_BUNDLE_FFF =
{ L("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } },
{ L("Infill") , { "fill_density", "fill_pattern" } },
{ L("Support material") , { "support_material", "support_material_auto", "support_material_threshold",
"support_material_pattern", "support_material_pattern", "support_material_interface_pattern", "support_material_buildplate_only",
"support_material_pattern", "support_material_interface_pattern", "support_material_buildplate_only",
"support_material_spacing" } },
{ L("Wipe options") , { "wipe_into_infill", "wipe_into_objects" } }
};
Expand Down Expand Up @@ -581,17 +581,30 @@ wxMenuItem* MenuFactory::append_menu_item_instance_to_object(wxMenu* menu)

wxMenuItem* MenuFactory::append_menu_item_printable(wxMenu* menu)
{
return append_menu_check_item(menu, wxID_ANY, _L("Printable"), "", [](wxCommandEvent&) {
const Selection& selection = plater()->canvas3D()->get_selection();
wxDataViewItem item;
if (obj_list()->GetSelectedItemsCount() > 1 && selection.is_single_full_object())
item = obj_list()->GetModel()->GetItemById(selection.get_object_idx());
else
item = obj_list()->GetSelection();

if (item)
obj_list()->toggle_printable_state(item);
}, menu);
wxMenuItem* menu_item_printable = append_menu_check_item(menu, wxID_ANY, _L("Printable"), "",
[](wxCommandEvent& ) { obj_list()->toggle_printable_state(); }, menu);

m_parent->Bind(wxEVT_UPDATE_UI, [](wxUpdateUIEvent& evt) {
ObjectList* list = obj_list();
wxDataViewItemArray sels;
list->GetSelections(sels);
wxDataViewItem frst_item = sels[0];
ItemType type = list->GetModel()->GetItemType(frst_item);
bool check;
if (type != itInstance && type != itObject)
check = false;
else {
int obj_idx = list->GetModel()->GetObjectIdByItem(frst_item);
int inst_idx = type == itObject ? 0 : list->GetModel()->GetInstanceIdByItem(frst_item);
check = list->object(obj_idx)->instances[inst_idx]->printable;
}

evt.Check(check);
plater()->set_current_canvas_as_dirty();

}, menu_item_printable->GetId());

return menu_item_printable;
}

void MenuFactory::append_menu_items_osx(wxMenu* menu)
Expand Down Expand Up @@ -800,7 +813,7 @@ void MenuFactory::create_common_object_menu(wxMenu* menu)
append_menu_item_instance_to_object(menu);
menu->AppendSeparator();

wxMenuItem* menu_item_printable = append_menu_item_printable(menu);
append_menu_item_printable(menu);
menu->AppendSeparator();

append_menu_item_reload_from_disk(menu);
Expand All @@ -810,16 +823,6 @@ void MenuFactory::create_common_object_menu(wxMenu* menu)

append_menu_item_fix_through_netfabb(menu);
append_menu_items_mirror(menu);

m_parent->Bind(wxEVT_UPDATE_UI, [](wxUpdateUIEvent& evt) {
const Selection& selection = get_selection();
int instance_idx = selection.get_instance_idx();
evt.Enable(selection.is_single_full_instance() || selection.is_single_full_object());
if (instance_idx != -1) {
evt.Check(obj_list()->object(selection.get_object_idx())->instances[instance_idx]->printable);
plater()->set_current_canvas_as_dirty();//view3D->set_as_dirty();
}
}, menu_item_printable->GetId());
}

void MenuFactory::create_object_menu()
Expand Down Expand Up @@ -882,6 +885,14 @@ void MenuFactory::create_part_menu()

}

void MenuFactory::create_instance_menu()
{
wxMenu* menu = &m_instance_menu;
// create "Instance to Object" menu item
append_menu_item_instance_to_object(menu);
append_menu_item_printable(menu);
}

void MenuFactory::init(wxWindow* parent)
{
m_parent = parent;
Expand All @@ -890,9 +901,7 @@ void MenuFactory::init(wxWindow* parent)
create_object_menu();
create_sla_object_menu();
create_part_menu();

// create "Instance to Object" menu item
append_menu_item_instance_to_object(&m_instance_menu);
create_instance_menu();
}

wxMenu* MenuFactory::default_menu()
Expand Down Expand Up @@ -959,6 +968,8 @@ wxMenu* MenuFactory::multi_selection_menu()
append_menu_item_merge_to_multipart_object(menu);
if (extruders_count() > 1)
append_menu_item_change_extruder(menu);
if (list_model()->GetItemType(sels[0]) != itVolume)
append_menu_item_printable(menu);

return menu;
}
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/GUI_Factories.hpp
Expand Up @@ -76,6 +76,7 @@ class MenuFactory
void create_object_menu();
void create_sla_object_menu();
void create_part_menu();
void create_instance_menu();

wxMenu* append_submenu_add_generic(wxMenu* menu, ModelVolumeType type);
void append_menu_items_add_volume(wxMenu* menu);
Expand Down
66 changes: 44 additions & 22 deletions src/slic3r/GUI/GUI_ObjectList.cpp
Expand Up @@ -837,7 +837,7 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me
{
const wxString title = col->GetTitle();
if (title == " ")
toggle_printable_state(item);
toggle_printable_state();
else if (title == _("Editing"))
show_context_menu(evt_context_menu);
else if (title == _("Name"))
Expand Down Expand Up @@ -3837,37 +3837,59 @@ void ObjectList::update_printable_state(int obj_idx, int instance_idx)
m_objects_model->SetPrintableState(printable, obj_idx, instance_idx);
}

void ObjectList::toggle_printable_state(wxDataViewItem item)
void ObjectList::toggle_printable_state()
{
const ItemType type = m_objects_model->GetItemType(item);
if (!(type&(itObject|itInstance/*|itVolume*/)))
wxDataViewItemArray sels;
GetSelections(sels);

wxDataViewItem frst_item = sels[0];

ItemType type = m_objects_model->GetItemType(frst_item);
if (!(type & (itObject | itInstance)))
return;

if (type & itObject)
{
const int obj_idx = m_objects_model->GetObjectIdByItem(item);
ModelObject* object = (*m_objects)[obj_idx];

// get object's printable and change it
const bool printable = !m_objects_model->IsPrintable(item);
int obj_idx = m_objects_model->GetObjectIdByItem(frst_item);
int inst_idx = type == itObject ? 0 : m_objects_model->GetInstanceIdByItem(frst_item);
bool printable = !object(obj_idx)->instances[inst_idx]->printable;

const wxString snapshot_text = from_u8((boost::format("%1% %2%")
% (printable ? _(L("Set Printable")) : _(L("Set Unprintable")))
% object->name).str());
take_snapshot(snapshot_text);
const wxString snapshot_text = sels.Count() > 1 ? (printable ? _L("Set Printable group") : _L("Set Unprintable group")) :
object(obj_idx)->instances.size() == 1 ? from_u8((boost::format("%1% %2%")
% (printable ? _L("Set Printable") : _L("Set Unprintable"))
% object(obj_idx)->name).str()) :
(printable ? _L("Set Printable Instance") : _L("Set Unprintable Instance"));
take_snapshot(snapshot_text);

// set printable value for all instances in object
for (auto inst : object->instances)
inst->printable = printable;
std::vector<size_t> obj_idxs;
for (auto item : sels)
{
type = m_objects_model->GetItemType(item);
if (!(type & (itObject | itInstance)))
continue;

// update printable state on canvas
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx);
obj_idx = m_objects_model->GetObjectIdByItem(item);
ModelObject* obj = object(obj_idx);

obj_idxs.emplace_back(static_cast<size_t>(obj_idx));

// set printable value for selected instance/instances in object
if (type == itInstance) {
inst_idx = m_objects_model->GetInstanceIdByItem(item);
obj->instances[m_objects_model->GetInstanceIdByItem(item)]->printable = printable;
}
else
for (auto inst : obj->instances)
inst->printable = printable;

// update printable state in ObjectList
m_objects_model->SetObjectPrintableState(printable ? piPrintable : piUnprintable , item);
m_objects_model->SetObjectPrintableState(printable ? piPrintable : piUnprintable, item);
}
else
wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state();

sort(obj_idxs.begin(), obj_idxs.end());
obj_idxs.erase(unique(obj_idxs.begin(), obj_idxs.end()), obj_idxs.end());

// update printable state on canvas
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs);

// update scene
wxGetApp().plater()->update();
Expand Down
2 changes: 1 addition & 1 deletion src/slic3r/GUI/GUI_ObjectList.hpp
Expand Up @@ -369,7 +369,7 @@ class ObjectList : public wxDataViewCtrl
void update_after_undo_redo();
//update printable state for item from objects model
void update_printable_state(int obj_idx, int instance_idx);
void toggle_printable_state(wxDataViewItem item);
void toggle_printable_state();

void set_extruder_for_selected_items(const int extruder) const ;

Expand Down
35 changes: 0 additions & 35 deletions src/slic3r/GUI/Selection.cpp
Expand Up @@ -1466,41 +1466,6 @@ std::vector<unsigned int> Selection::get_unselected_volume_idxs_from(const std::
return idxs;
}

void Selection::toggle_instance_printable_state()
{
int instance_idx = get_instance_idx();
if (instance_idx == -1)
return;

int obj_idx = get_object_idx();
if ((0 <= obj_idx) && (obj_idx < (int)m_model->objects.size()))
{
ModelObject* model_object = m_model->objects[obj_idx];
if ((0 <= instance_idx) && (instance_idx < (int)model_object->instances.size()))
{
ModelInstance* instance = model_object->instances[instance_idx];
const bool printable = !instance->printable;

wxString snapshot_text = model_object->instances.size() == 1 ? from_u8((boost::format("%1% %2%")
% (printable ? _utf8(L("Set Printable")) : _utf8(L("Set Unprintable")))
% model_object->name).str()) :
(printable ? _(L("Set Printable Instance")) : _(L("Set Unprintable Instance")));
wxGetApp().plater()->take_snapshot(snapshot_text);

instance->printable = printable;

for (GLVolume* volume : *m_volumes)
{
if ((volume->object_idx() == obj_idx) && (volume->instance_idx() == instance_idx))
volume->printable = instance->printable;
}

wxGetApp().obj_list()->update_printable_state(obj_idx, instance_idx);
wxGetApp().plater()->update();
}
}
}

void Selection::update_valid()
{
m_valid = (m_volumes != nullptr) && (m_model != nullptr);
Expand Down
3 changes: 1 addition & 2 deletions src/slic3r/GUI/Selection.hpp
Expand Up @@ -286,6 +286,7 @@ class Selection
bool is_from_single_instance() const { return get_instance_idx() != -1; }
bool is_from_single_object() const;
bool is_sla_compliant() const;
bool is_instance_mode() const { return m_mode == Instance; }

bool contains_volume(unsigned int volume_idx) const { return m_list.find(volume_idx) != m_list.end(); }
// returns true if the selection contains all the given indices
Expand Down Expand Up @@ -355,8 +356,6 @@ class Selection
// returns the list of idxs of the volumes contained in the given list but not in the selection
std::vector<unsigned int> get_unselected_volume_idxs_from(const std::vector<unsigned int>& volume_idxs) const;

void toggle_instance_printable_state();

private:
void update_valid();
void update_type();
Expand Down

0 comments on commit 3a53606

Please sign in to comment.