NEW:add "Sub merge" function

jira: github 5855
Change-Id: I7f21a0340245aec4d47f56b2f0584a5cf08d81f7
This commit is contained in:
zhou.xu 2025-02-25 10:41:14 +08:00 committed by lane.wei
parent fba3ab060f
commit e670cd8494
4 changed files with 115 additions and 1 deletions

View File

@ -1600,12 +1600,26 @@ wxMenu* MenuFactory::multi_selection_menu()
wxDataViewItemArray sels; wxDataViewItemArray sels;
obj_list()->GetSelections(sels); obj_list()->GetSelections(sels);
bool multi_volume = true; bool multi_volume = true;
int count = 0;
int obj_idx = -1;
for (const wxDataViewItem& item : sels) { for (const wxDataViewItem& item : sels) {
multi_volume = list_model()->GetItemType(item) & itVolume; multi_volume = list_model()->GetItemType(item) & itVolume;
if (!(list_model()->GetItemType(item) & (itVolume | itObject | itInstance))) if (!(list_model()->GetItemType(item) & (itVolume | itObject | itInstance)))
// show this menu only for Objects(Instances mixed with Objects)/Volumes selection // show this menu only for Objects(Instances mixed with Objects)/Volumes selection
return nullptr; return nullptr;
if (multi_volume) {
auto temp_obj_idx = obj_list()->GetModel()->GetObjectIdByItem(item);
if (temp_obj_idx >= 0 && temp_obj_idx != obj_idx) {
if (obj_idx == -1) {
obj_idx = temp_obj_idx;
}
else {
multi_volume = false;
break;
}
}
}
count++;
} }
wxMenu* menu = new MenuWithSeparators(); wxMenu* menu = new MenuWithSeparators();
@ -1632,6 +1646,10 @@ wxMenu* MenuFactory::multi_selection_menu()
} }
else { else {
append_menu_item_center(menu); append_menu_item_center(menu);
auto mo = (*obj_list()->objects())[obj_idx];
if (count < mo->volumes.size()) {
append_menu_item_sub_merge(menu);
}
append_menu_item_fix_through_netfabb(menu); append_menu_item_fix_through_netfabb(menu);
//append_menu_item_simplify(menu); //append_menu_item_simplify(menu);
append_menu_item_delete(menu); append_menu_item_delete(menu);
@ -1787,6 +1805,26 @@ void MenuFactory::append_menu_item_center(wxMenu* menu)
}, m_parent); }, m_parent);
} }
void MenuFactory::append_menu_item_sub_merge(wxMenu *menu)
{
append_menu_item(
menu, wxID_ANY, _L("Sub merge"), "",
[this](wxCommandEvent &) {
obj_list()->add_new_model_object_from_old_object();
},
"", nullptr,
[]() {
if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
return false;
else {
if (obj_list()->has_selected_cut_object())
return false;
return true;
}
},
m_parent);
}
void MenuFactory::append_menu_item_per_object_process(wxMenu* menu) void MenuFactory::append_menu_item_per_object_process(wxMenu* menu)
{ {
const std::vector<wxString> names = { _L("Edit Process Settings"), _L("Edit Process Settings") }; const std::vector<wxString> names = { _L("Edit Process Settings"), _L("Edit Process Settings") };

View File

@ -171,6 +171,7 @@ private:
void append_menu_item_clone(wxMenu* menu); void append_menu_item_clone(wxMenu* menu);
void append_menu_item_simplify(wxMenu* menu); void append_menu_item_simplify(wxMenu* menu);
void append_menu_item_center(wxMenu* menu); void append_menu_item_center(wxMenu* menu);
void append_menu_item_sub_merge(wxMenu *menu);
void append_menu_item_per_object_process(wxMenu* menu); void append_menu_item_per_object_process(wxMenu* menu);
void append_menu_item_per_object_settings(wxMenu* menu); void append_menu_item_per_object_settings(wxMenu* menu);
void append_menu_item_change_filament(wxMenu* menu); void append_menu_item_change_filament(wxMenu* menu);

View File

@ -2362,6 +2362,80 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
} }
} }
void GUI::ObjectList::add_new_model_object_from_old_object() {
const Selection &selection = scene_selection();
int instance_idx = *selection.get_instance_idxs().begin();
assert(instance_idx != -1);
if (instance_idx == -1)
return;
wxDataViewItemArray sels;
GetSelections(sels);
if (sels.IsEmpty()) return;
int obj_idx = -1;
std::vector<int> vol_idxs;
for (wxDataViewItem item : sels) {
const int temp_obj_idx = m_objects_model->GetObjectIdByItem(item);
if (temp_obj_idx < 0) //&& object(obj_idx)->is_cut()
return;
obj_idx = temp_obj_idx;
const int vol_idx = m_objects_model->GetVolumeIdByItem(item);
vol_idxs.emplace_back(vol_idx);
}
if (vol_idxs.empty()) {
return;
}
take_snapshot("Add new model object");
wxBusyCursor cursor;
std::sort(vol_idxs.begin(), vol_idxs.end());
ModelVolumePtrs sel_volumes;
auto mo = (*m_objects)[obj_idx];
for (int i = vol_idxs.size() - 1; i >= 0; i--) {
if (vol_idxs[i] > mo->volumes.size()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "check error:array bound";
continue;
}
auto vol_idx = vol_idxs[i];
auto mv = mo->volumes[vol_idx];
sel_volumes.emplace_back(mv);
mo->volumes.erase(mo->volumes.begin() + vol_idx);
}
for (int i = vol_idxs.size() - 1; i >= 0; i--) {
auto vol_idx = vol_idxs[i];
delete_volume_from_list(obj_idx, vol_idx);
}
// Add mesh to model as a new object
Model &model = wxGetApp().plater()->model();
std::vector<size_t> object_idxs;
ModelObject * new_object = model.add_object();
new_object->name = into_u8("Sub merge");
new_object->add_instance(); // each object should have at least one instance
int min_extruder = (int) EnforcerBlockerType::ExtruderMax - 1;
for (auto mv : sel_volumes) {
new_object->add_volume(*mv, mv->type());
auto option = mv->config.option("extruder");
if (option) {
auto volume_extruder_id = (dynamic_cast<const ConfigOptionInt *>(option))->getInt();
if (min_extruder > volume_extruder_id) {
min_extruder = volume_extruder_id;
}
}
}
new_object->sort_volumes(true);
// set a default extruder value, since user can't add it manually
new_object->config.set_key_value("extruder", new ConfigOptionInt(min_extruder));
new_object->invalidate_bounding_box();
new_object->instances[0]->set_transformation(mo->instances[0]->get_transformation());
// BBS: backup
Slic3r::save_object_mesh(*new_object);
new_object->ensure_on_bed();
// BBS init assmeble transformation
new_object->get_model()->set_assembly_pos(new_object);
object_idxs.push_back(model.objects.size() - 1);
paste_objects_into_list(object_idxs);
wxGetApp().mainframe->update_title();
}
void ObjectList::switch_to_object_process() void ObjectList::switch_to_object_process()
{ {
wxGetApp().params_panel()->switch_to_object(true); wxGetApp().params_panel()->switch_to_object(true);

View File

@ -288,6 +288,7 @@ public:
//void load_part(ModelObject& model_object, std::vector<ModelVolume*>& added_volumes, ModelVolumeType type, bool from_galery = false); //void load_part(ModelObject& model_object, std::vector<ModelVolume*>& added_volumes, ModelVolumeType type, bool from_galery = false);
void load_modifier(const wxArrayString& input_files, ModelObject& model_object, std::vector<ModelVolume*>& added_volumes, ModelVolumeType type, bool from_galery = false); void load_modifier(const wxArrayString& input_files, ModelObject& model_object, std::vector<ModelVolume*>& added_volumes, ModelVolumeType type, bool from_galery = false);
void load_generic_subobject(const std::string& type_name, const ModelVolumeType type); void load_generic_subobject(const std::string& type_name, const ModelVolumeType type);
void add_new_model_object_from_old_object();
void load_shape_object(const std::string &type_name); void load_shape_object(const std::string &type_name);
void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true); void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true);
// BBS // BBS