diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 092ba2756..4e92c4570 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1023,14 +1023,6 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) update_settings_list(); } -bool cur_item_hase_children() -{ - wxDataViewItemArray children; - if (m_objects_model->GetChildren(m_objects_ctrl->GetSelection(), children) > 0) - return true; - return false; -} - wxMenuItem* menu_item_split(wxMenu* menu, int id) { auto menu_item = new wxMenuItem(menu, id, _(L("Split to parts"))); menu_item->SetBitmap(m_bmp_split); @@ -1064,7 +1056,7 @@ wxMenu *create_add_part_popupmenu() menu->AppendSeparator(); auto menu_item = menu_item_split(menu, config_id_base + i); menu->Append(menu_item); - menu_item->Enable(!cur_item_hase_children()); + menu_item->Enable(is_splittable_object(false)); menu->AppendSeparator(); // Append settings popupmenu @@ -1100,7 +1092,9 @@ wxMenu *create_part_settings_popupmenu() wxMenu *menu = new wxMenu; wxWindowID config_id_base = wxWindow::NewControlId(2); - menu->Append(menu_item_split(menu, config_id_base)); + auto menu_item = menu_item_split(menu, config_id_base); + menu->Append(menu_item); + menu_item->Enable(is_splittable_object(true)); menu->AppendSeparator(); // Append settings popupmenu @@ -1332,23 +1326,54 @@ void on_btn_del() part_selection_changed(); } +bool get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume) +{ + if (!item || m_selected_object_id < 0) + return false; + const auto volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id < 0) { + if (split_part) return false; + volume = (*m_objects)[m_selected_object_id]->volumes[0]; + } + else + volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; + if (volume) + return true; + return false; +} + +bool is_splittable_object(const bool split_part) +{ + const wxDataViewItem item = m_objects_ctrl->GetSelection(); + if (!item) return false; + + wxDataViewItemArray children; + if (!split_part && m_objects_model->GetChildren(item, children) > 0) + return false; + + ModelVolume* volume; + if (!get_volume_by_item(split_part, item, volume) || !volume) + return false; + + TriangleMeshPtrs meshptrs = volume->mesh.split(); + if (meshptrs.size() <= 1) { + delete meshptrs.front(); + return false; + } + + return true; +} + void on_btn_split(const bool split_part) { - auto item = m_objects_ctrl->GetSelection(); + const auto item = m_objects_ctrl->GetSelection(); if (!item || m_selected_object_id<0) return; - auto volume_id = m_objects_model->GetVolumeIdByItem(item); ModelVolume* volume; - if (volume_id < 0) { - if (split_part) return; - else - volume = (*m_objects)[m_selected_object_id]->volumes[0]; } - else - volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; - DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config; - auto nozzle_dmrs_cnt = config.option("nozzle_diameter")->values.size(); - auto split_rez = volume->split(nozzle_dmrs_cnt); - if (split_rez == 1) { + if (!get_volume_by_item(split_part, item, volume)) return; + DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config; + const auto nozzle_dmrs_cnt = config.option("nozzle_diameter")->values.size(); + if (volume->split(nozzle_dmrs_cnt) == 1) { wxMessageBox(_(L("The selected object couldn't be split because it contains only one part."))); return; } diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 630912fb4..5d94ecc3d 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -79,6 +79,7 @@ void object_ctrl_context_menu(); void object_ctrl_key_event(wxKeyEvent& event); void object_ctrl_item_value_change(wxDataViewEvent& event); void show_context_menu(); +bool is_splittable_object(const bool split_part); void init_mesh_icons(); void set_event_object_selection_changed(const int& event); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 1642828fb..54454fbf7 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -442,7 +442,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_ const wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder); if (create_frst_child && (root->GetChildren().Count() == 0 || - (root->GetChildren().Count() == 1 && root->GetChildren().Item(0)->m_type == "settings"))) + (root->GetChildren().Count() == 1 && root->GetNthChild(0)->m_type == "settings"))) { const auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG); const auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, extruder_str, 0); @@ -452,7 +452,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_ ItemAdded(parent_item, child); } - const auto volume_id = root->GetChildren().Item(0)->m_type == "settings" ? + const auto volume_id = root->GetChildCount() > 0 && root->GetNthChild(0)->m_type == "settings" ? root->GetChildCount() - 1 : root->GetChildCount(); const auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, volume_id); @@ -597,7 +597,7 @@ int PrusaObjectDataViewModel::GetIdByItem(wxDataViewItem& item) return it - m_objects.begin(); } -int PrusaObjectDataViewModel::GetVolumeIdByItem(wxDataViewItem& item) +int PrusaObjectDataViewModel::GetVolumeIdByItem(const wxDataViewItem& item) { wxASSERT(item.IsOk()); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index cefe680aa..4236e0915 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -368,7 +368,7 @@ public: void DeleteChildren(wxDataViewItem& parent); wxDataViewItem GetItemById(int obj_idx); int GetIdByItem(wxDataViewItem& item); - int GetVolumeIdByItem(wxDataViewItem& item); + int GetVolumeIdByItem(const wxDataViewItem& item); bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog