mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 09:17:52 -06:00
Added "Printable" menu item for multiple selection
This commit is contained in:
parent
cfcce6f29a
commit
3a5360651d
6 changed files with 83 additions and 85 deletions
|
@ -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("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } },
|
||||||
{ L("Infill") , { "fill_density", "fill_pattern" } },
|
{ L("Infill") , { "fill_density", "fill_pattern" } },
|
||||||
{ L("Support material") , { "support_material", "support_material_auto", "support_material_threshold",
|
{ 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" } },
|
"support_material_spacing" } },
|
||||||
{ L("Wipe options") , { "wipe_into_infill", "wipe_into_objects" } }
|
{ L("Wipe options") , { "wipe_into_infill", "wipe_into_objects" } }
|
||||||
};
|
};
|
||||||
|
@ -581,17 +581,30 @@ wxMenuItem* MenuFactory::append_menu_item_instance_to_object(wxMenu* menu)
|
||||||
|
|
||||||
wxMenuItem* MenuFactory::append_menu_item_printable(wxMenu* menu)
|
wxMenuItem* MenuFactory::append_menu_item_printable(wxMenu* menu)
|
||||||
{
|
{
|
||||||
return append_menu_check_item(menu, wxID_ANY, _L("Printable"), "", [](wxCommandEvent&) {
|
wxMenuItem* menu_item_printable = append_menu_check_item(menu, wxID_ANY, _L("Printable"), "",
|
||||||
const Selection& selection = plater()->canvas3D()->get_selection();
|
[](wxCommandEvent& ) { obj_list()->toggle_printable_state(); }, menu);
|
||||||
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)
|
m_parent->Bind(wxEVT_UPDATE_UI, [](wxUpdateUIEvent& evt) {
|
||||||
obj_list()->toggle_printable_state(item);
|
ObjectList* list = obj_list();
|
||||||
}, menu);
|
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)
|
void MenuFactory::append_menu_items_osx(wxMenu* menu)
|
||||||
|
@ -800,7 +813,7 @@ void MenuFactory::create_common_object_menu(wxMenu* menu)
|
||||||
append_menu_item_instance_to_object(menu);
|
append_menu_item_instance_to_object(menu);
|
||||||
menu->AppendSeparator();
|
menu->AppendSeparator();
|
||||||
|
|
||||||
wxMenuItem* menu_item_printable = append_menu_item_printable(menu);
|
append_menu_item_printable(menu);
|
||||||
menu->AppendSeparator();
|
menu->AppendSeparator();
|
||||||
|
|
||||||
append_menu_item_reload_from_disk(menu);
|
append_menu_item_reload_from_disk(menu);
|
||||||
|
@ -810,16 +823,6 @@ void MenuFactory::create_common_object_menu(wxMenu* menu)
|
||||||
|
|
||||||
append_menu_item_fix_through_netfabb(menu);
|
append_menu_item_fix_through_netfabb(menu);
|
||||||
append_menu_items_mirror(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()
|
void MenuFactory::create_object_menu()
|
||||||
|
@ -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)
|
void MenuFactory::init(wxWindow* parent)
|
||||||
{
|
{
|
||||||
m_parent = parent;
|
m_parent = parent;
|
||||||
|
@ -890,9 +901,7 @@ void MenuFactory::init(wxWindow* parent)
|
||||||
create_object_menu();
|
create_object_menu();
|
||||||
create_sla_object_menu();
|
create_sla_object_menu();
|
||||||
create_part_menu();
|
create_part_menu();
|
||||||
|
create_instance_menu();
|
||||||
// create "Instance to Object" menu item
|
|
||||||
append_menu_item_instance_to_object(&m_instance_menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenu* MenuFactory::default_menu()
|
wxMenu* MenuFactory::default_menu()
|
||||||
|
@ -959,6 +968,8 @@ wxMenu* MenuFactory::multi_selection_menu()
|
||||||
append_menu_item_merge_to_multipart_object(menu);
|
append_menu_item_merge_to_multipart_object(menu);
|
||||||
if (extruders_count() > 1)
|
if (extruders_count() > 1)
|
||||||
append_menu_item_change_extruder(menu);
|
append_menu_item_change_extruder(menu);
|
||||||
|
if (list_model()->GetItemType(sels[0]) != itVolume)
|
||||||
|
append_menu_item_printable(menu);
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ private:
|
||||||
void create_object_menu();
|
void create_object_menu();
|
||||||
void create_sla_object_menu();
|
void create_sla_object_menu();
|
||||||
void create_part_menu();
|
void create_part_menu();
|
||||||
|
void create_instance_menu();
|
||||||
|
|
||||||
wxMenu* append_submenu_add_generic(wxMenu* menu, ModelVolumeType type);
|
wxMenu* append_submenu_add_generic(wxMenu* menu, ModelVolumeType type);
|
||||||
void append_menu_items_add_volume(wxMenu* menu);
|
void append_menu_items_add_volume(wxMenu* menu);
|
||||||
|
|
|
@ -837,7 +837,7 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me
|
||||||
{
|
{
|
||||||
const wxString title = col->GetTitle();
|
const wxString title = col->GetTitle();
|
||||||
if (title == " ")
|
if (title == " ")
|
||||||
toggle_printable_state(item);
|
toggle_printable_state();
|
||||||
else if (title == _("Editing"))
|
else if (title == _("Editing"))
|
||||||
show_context_menu(evt_context_menu);
|
show_context_menu(evt_context_menu);
|
||||||
else if (title == _("Name"))
|
else if (title == _("Name"))
|
||||||
|
@ -3837,37 +3837,59 @@ void ObjectList::update_printable_state(int obj_idx, int instance_idx)
|
||||||
m_objects_model->SetPrintableState(printable, obj_idx, 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);
|
wxDataViewItemArray sels;
|
||||||
if (!(type&(itObject|itInstance/*|itVolume*/)))
|
GetSelections(sels);
|
||||||
|
|
||||||
|
wxDataViewItem frst_item = sels[0];
|
||||||
|
|
||||||
|
ItemType type = m_objects_model->GetItemType(frst_item);
|
||||||
|
if (!(type & (itObject | itInstance)))
|
||||||
return;
|
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
|
int obj_idx = m_objects_model->GetObjectIdByItem(frst_item);
|
||||||
const bool printable = !m_objects_model->IsPrintable(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%")
|
const wxString snapshot_text = sels.Count() > 1 ? (printable ? _L("Set Printable group") : _L("Set Unprintable group")) :
|
||||||
% (printable ? _(L("Set Printable")) : _(L("Set Unprintable")))
|
object(obj_idx)->instances.size() == 1 ? from_u8((boost::format("%1% %2%")
|
||||||
% object->name).str());
|
% (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);
|
take_snapshot(snapshot_text);
|
||||||
|
|
||||||
// set printable value for all instances in object
|
std::vector<size_t> obj_idxs;
|
||||||
for (auto inst : object->instances)
|
for (auto item : sels)
|
||||||
inst->printable = printable;
|
{
|
||||||
|
type = m_objects_model->GetItemType(item);
|
||||||
|
if (!(type & (itObject | itInstance)))
|
||||||
|
continue;
|
||||||
|
|
||||||
// update printable state on canvas
|
obj_idx = m_objects_model->GetObjectIdByItem(item);
|
||||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx);
|
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
|
// 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
|
// update scene
|
||||||
wxGetApp().plater()->update();
|
wxGetApp().plater()->update();
|
||||||
|
|
|
@ -369,7 +369,7 @@ public:
|
||||||
void update_after_undo_redo();
|
void update_after_undo_redo();
|
||||||
//update printable state for item from objects model
|
//update printable state for item from objects model
|
||||||
void update_printable_state(int obj_idx, int instance_idx);
|
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 ;
|
void set_extruder_for_selected_items(const int extruder) const ;
|
||||||
|
|
||||||
|
|
|
@ -1466,41 +1466,6 @@ std::vector<unsigned int> Selection::get_unselected_volume_idxs_from(const std::
|
||||||
return idxs;
|
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()
|
void Selection::update_valid()
|
||||||
{
|
{
|
||||||
m_valid = (m_volumes != nullptr) && (m_model != nullptr);
|
m_valid = (m_volumes != nullptr) && (m_model != nullptr);
|
||||||
|
|
|
@ -286,6 +286,7 @@ public:
|
||||||
bool is_from_single_instance() const { return get_instance_idx() != -1; }
|
bool is_from_single_instance() const { return get_instance_idx() != -1; }
|
||||||
bool is_from_single_object() const;
|
bool is_from_single_object() const;
|
||||||
bool is_sla_compliant() 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(); }
|
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
|
// returns true if the selection contains all the given indices
|
||||||
|
@ -355,8 +356,6 @@ public:
|
||||||
// returns the list of idxs of the volumes contained in the given list but not in the 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;
|
std::vector<unsigned int> get_unselected_volume_idxs_from(const std::vector<unsigned int>& volume_idxs) const;
|
||||||
|
|
||||||
void toggle_instance_printable_state();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update_valid();
|
void update_valid();
|
||||||
void update_type();
|
void update_type();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue