mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge branch 'dev' of https://github.com/prusa3d/PrusaSlicer into dev
This commit is contained in:
		
						commit
						0de8245432
					
				
					 4 changed files with 126 additions and 34 deletions
				
			
		|  | @ -279,6 +279,7 @@ void ObjectList::create_popup_menus() | |||
|     create_part_popupmenu(&m_menu_part); | ||||
|     create_sla_object_popupmenu(&m_menu_sla_object); | ||||
|     create_instance_popupmenu(&m_menu_instance); | ||||
|     create_default_popupmenu(&m_menu_default); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::get_selected_item_indexes(int& obj_idx, int& vol_idx, const wxDataViewItem& input_item/* = wxDataViewItem(nullptr)*/) | ||||
|  | @ -783,18 +784,23 @@ void ObjectList::OnChar(wxKeyEvent& event) | |||
| 
 | ||||
| void ObjectList::OnContextMenu(wxDataViewEvent&) | ||||
| { | ||||
|     list_manipulation(); | ||||
|     list_manipulation(true); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::list_manipulation() | ||||
| void ObjectList::list_manipulation(bool evt_context_menu/* = false*/) | ||||
| { | ||||
|     wxDataViewItem item; | ||||
|     wxDataViewColumn* col = nullptr; | ||||
|     const wxPoint pt = get_mouse_position_in_control(); | ||||
|     HitTest(pt, item, col); | ||||
| 
 | ||||
|     if (!item || col == nullptr) { | ||||
|         return; | ||||
|     if (!item) { | ||||
|         if (col == nullptr) | ||||
|             return; | ||||
|         if (evt_context_menu) { | ||||
|             show_context_menu(evt_context_menu); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     const wxString title = col->GetTitle(); | ||||
|  | @ -802,7 +808,7 @@ void ObjectList::list_manipulation() | |||
|     if (title == " ") | ||||
|         toggle_printable_state(item); | ||||
|     else if (title == _("Editing")) | ||||
|         show_context_menu(); | ||||
|         show_context_menu(evt_context_menu); | ||||
|     else if (title == _("Name")) | ||||
|     { | ||||
|         int obj_idx, vol_idx; | ||||
|  | @ -818,7 +824,7 @@ void ObjectList::list_manipulation() | |||
| #endif //__WXMSW__
 | ||||
| } | ||||
| 
 | ||||
| void ObjectList::show_context_menu() | ||||
| void ObjectList::show_context_menu(const bool evt_context_menu) | ||||
| { | ||||
|     if (multiple_selection()) | ||||
|     { | ||||
|  | @ -831,22 +837,26 @@ void ObjectList::show_context_menu() | |||
|     } | ||||
| 
 | ||||
|     const auto item = GetSelection(); | ||||
|     wxMenu* menu {nullptr}; | ||||
|     if (item) | ||||
|     { | ||||
|         const ItemType type = m_objects_model->GetItemType(item); | ||||
|         if (!(type & (itObject | itVolume | itLayer | itInstance))) | ||||
|             return; | ||||
| 
 | ||||
|         wxMenu* menu = type & itInstance ? &m_menu_instance : | ||||
|         menu = type & itInstance ? &m_menu_instance : | ||||
|                        type & itLayer ? &m_menu_layer : | ||||
|                        m_objects_model->GetParent(item) != wxDataViewItem(nullptr) ? &m_menu_part : | ||||
|                        printer_technology() == ptFFF ? &m_menu_object : &m_menu_sla_object; | ||||
| 
 | ||||
|         if (!(type & itInstance)) | ||||
|             append_menu_item_settings(menu); | ||||
| 
 | ||||
|         wxGetApp().plater()->PopupMenu(menu); | ||||
|     } | ||||
|     else if (evt_context_menu) | ||||
|         menu = &m_menu_default; | ||||
| 
 | ||||
|     if (menu) | ||||
|         wxGetApp().plater()->PopupMenu(menu); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::copy() | ||||
|  | @ -1286,13 +1296,16 @@ void ObjectList::show_settings(const wxDataViewItem settings_item) | |||
| wxMenu* ObjectList::append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type) { | ||||
|     auto sub_menu = new wxMenu; | ||||
| 
 | ||||
|     if (wxGetApp().get_mode() == comExpert) { | ||||
|     if (wxGetApp().get_mode() == comExpert && type != ModelVolumeType::INVALID) { | ||||
|     append_menu_item(sub_menu, wxID_ANY, _(L("Load")) + " " + dots, "", | ||||
|         [this, type](wxCommandEvent&) { load_subobject(type); }, "", menu); | ||||
|     sub_menu->AppendSeparator(); | ||||
|     } | ||||
| 
 | ||||
|     for (auto& item : { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") }) { | ||||
|     for (auto& item : { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") }) | ||||
|     { | ||||
|         if (type == ModelVolumeType::INVALID && item == "Slab") | ||||
|             continue; | ||||
|         append_menu_item(sub_menu, wxID_ANY, _(item), "", | ||||
|             [this, type, item](wxCommandEvent&) { load_generic_subobject(item, type); }, "", menu); | ||||
|     } | ||||
|  | @ -1579,6 +1592,12 @@ void ObjectList::create_instance_popupmenu(wxMenu*menu) | |||
|     }, m_menu_item_split_instances->GetId()); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::create_default_popupmenu(wxMenu*menu) | ||||
| { | ||||
|     wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType::INVALID); | ||||
|     append_submenu(menu, sub_menu, wxID_ANY, _(L("Add Shape")), "", "add_part"); | ||||
| } | ||||
| 
 | ||||
| wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu) | ||||
| { | ||||
|     wxMenu *menu = new wxMenu; | ||||
|  | @ -1717,8 +1736,38 @@ void ObjectList::load_part( ModelObject* model_object, | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| static TriangleMesh create_mesh(const std::string& type_name, const BoundingBoxf3& bb) | ||||
| { | ||||
|     TriangleMesh mesh; | ||||
| 
 | ||||
|     const double side = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.1); | ||||
| 
 | ||||
|     if (type_name == "Box") | ||||
|         // Sitting on the print bed, left front front corner at (0, 0).
 | ||||
|         mesh = make_cube(side, side, side); | ||||
|     else if (type_name == "Cylinder") | ||||
|         // Centered around 0, sitting on the print bed.
 | ||||
|         // The cylinder has the same volume as the box above.
 | ||||
|         mesh = make_cylinder(0.564 * side, side); | ||||
|     else if (type_name == "Sphere") | ||||
|         // Centered around 0, half the sphere below the print bed, half above.
 | ||||
|         // The sphere has the same volume as the box above.
 | ||||
|         mesh = make_sphere(0.62 * side, PI / 18); | ||||
|     else if (type_name == "Slab") | ||||
|         // Sitting on the print bed, left front front corner at (0, 0).
 | ||||
|         mesh = make_cube(bb.size().x() * 1.5, bb.size().y() * 1.5, bb.size().z() * 0.5); | ||||
|     mesh.repair(); | ||||
| 
 | ||||
|     return mesh; | ||||
| } | ||||
| 
 | ||||
| void ObjectList::load_generic_subobject(const std::string& type_name, const ModelVolumeType type) | ||||
| { | ||||
|     if (type == ModelVolumeType::INVALID) { | ||||
|         load_shape_object(type_name); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const int obj_idx = get_selected_obj_idx(); | ||||
|     if (obj_idx < 0)  | ||||
|         return; | ||||
|  | @ -1741,26 +1790,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode | |||
|     // Bounding box of the selected instance in world coordinate system including the translation, without modifiers.
 | ||||
|     BoundingBoxf3 instance_bb = model_object.instance_bounding_box(instance_idx); | ||||
| 
 | ||||
|     const wxString name = _(L("Generic")) + "-" + _(type_name); | ||||
|     TriangleMesh mesh; | ||||
| 
 | ||||
|     double side = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.1); | ||||
| 
 | ||||
|     if (type_name == "Box") | ||||
|         // Sitting on the print bed, left front front corner at (0, 0).
 | ||||
|         mesh = make_cube(side, side, side); | ||||
|     else if (type_name == "Cylinder") | ||||
|         // Centered around 0, sitting on the print bed.
 | ||||
|         // The cylinder has the same volume as the box above.
 | ||||
|         mesh = make_cylinder(0.564 * side, side); | ||||
|     else if (type_name == "Sphere") | ||||
|         // Centered around 0, half the sphere below the print bed, half above.
 | ||||
|         // The sphere has the same volume as the box above.
 | ||||
|         mesh = make_sphere(0.62 * side, PI / 18); | ||||
|     else if (type_name == "Slab") | ||||
|         // Sitting on the print bed, left front front corner at (0, 0).
 | ||||
|         mesh = make_cube(instance_bb.size().x()*1.5, instance_bb.size().y()*1.5, instance_bb.size().z()*0.5); | ||||
|     mesh.repair(); | ||||
|     TriangleMesh mesh = create_mesh(type_name, instance_bb); | ||||
|      | ||||
| 	// Mesh will be centered when loading.
 | ||||
|     ModelVolume *new_volume = model_object.add_volume(std::move(mesh)); | ||||
|  | @ -1782,6 +1812,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode | |||
|         new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset); | ||||
|     } | ||||
| 
 | ||||
|     const wxString name = _(L("Generic")) + "-" + _(type_name); | ||||
|     new_volume->name = into_u8(name); | ||||
|     // set a default extruder value, since user can't add it manually
 | ||||
|     new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); | ||||
|  | @ -1799,6 +1830,57 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode | |||
| #endif //no __WXOSX__ //__WXMSW__
 | ||||
| } | ||||
| 
 | ||||
| void ObjectList::load_shape_object(const std::string& type_name) | ||||
| { | ||||
|     const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); | ||||
|     assert(selection.get_object_idx() == -1); // Add nothing is something is selected on 3DScene
 | ||||
|     if (selection.get_object_idx() != -1) | ||||
|         return; | ||||
| 
 | ||||
|     const int obj_idx = m_objects->size(); | ||||
|     if (obj_idx < 0) | ||||
|         return; | ||||
| 
 | ||||
|     take_snapshot(_(L("Add Shape"))); | ||||
| 
 | ||||
|     // Create mesh
 | ||||
|     BoundingBoxf3 bb; | ||||
|     TriangleMesh mesh = create_mesh(type_name, bb); | ||||
| 
 | ||||
|     // Add mesh to model as a new object
 | ||||
|     Model& model = wxGetApp().plater()->model(); | ||||
|     const wxString name = _(L("Shape")) + "-" + _(type_name); | ||||
| 
 | ||||
| #ifdef _DEBUG | ||||
|     check_model_ids_validity(model); | ||||
| #endif /* _DEBUG */ | ||||
| 
 | ||||
|     std::vector<size_t> object_idxs; | ||||
|     ModelObject* new_object = model.add_object(); | ||||
|     new_object->name = into_u8(name); | ||||
|     new_object->add_instance(); // each object should have at list one instance
 | ||||
| 
 | ||||
|     ModelVolume* new_volume = new_object->add_volume(mesh); | ||||
|     new_volume->name = into_u8(name); | ||||
|     // set a default extruder value, since user can't add it manually
 | ||||
|     new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); | ||||
|     new_object->invalidate_bounding_box(); | ||||
| 
 | ||||
|     const BoundingBoxf bed_shape = wxGetApp().plater()->bed_shape_bb(); | ||||
|     new_object->instances[0]->set_offset(Slic3r::to_3d(bed_shape.center().cast<double>(), -new_object->origin_translation(2))); | ||||
| 
 | ||||
|     object_idxs.push_back(model.objects.size() - 1); | ||||
| #ifdef _DEBUG | ||||
|     check_model_ids_validity(model); | ||||
| #endif /* _DEBUG */ | ||||
| 
 | ||||
|     paste_objects_into_list(object_idxs); | ||||
| 
 | ||||
| #ifdef _DEBUG | ||||
|     check_model_ids_validity(model); | ||||
| #endif /* _DEBUG */ | ||||
| } | ||||
| 
 | ||||
| void ObjectList::del_object(const int obj_idx) | ||||
| { | ||||
|     wxGetApp().plater()->delete_object_from_model(obj_idx); | ||||
|  | @ -3585,7 +3667,8 @@ void ObjectList::msw_rescale() | |||
|                                       &m_menu_part,  | ||||
|                                       &m_menu_sla_object,  | ||||
|                                       &m_menu_instance,  | ||||
|                                       &m_menu_layer }) | ||||
|                                       &m_menu_layer, | ||||
|                                       &m_menu_default}) | ||||
|         msw_rescale_menu(menu); | ||||
| 
 | ||||
|     Layout(); | ||||
|  |  | |||
|  | @ -132,6 +132,7 @@ private: | |||
|     MenuWithSeparators  m_menu_sla_object; | ||||
|     MenuWithSeparators  m_menu_instance; | ||||
|     MenuWithSeparators  m_menu_layer; | ||||
|     MenuWithSeparators  m_menu_default; | ||||
|     wxMenuItem* m_menu_item_settings { nullptr }; | ||||
|     wxMenuItem* m_menu_item_split_instances { nullptr }; | ||||
| 
 | ||||
|  | @ -208,7 +209,7 @@ public: | |||
|     void                set_tooltip_for_item(const wxPoint& pt); | ||||
| 
 | ||||
|     void                selection_changed(); | ||||
|     void                show_context_menu(); | ||||
|     void                show_context_menu(const bool evt_context_menu); | ||||
| #ifndef __WXOSX__ | ||||
|     void                key_event(wxKeyEvent& event); | ||||
| #endif /* __WXOSX__ */ | ||||
|  | @ -240,6 +241,7 @@ public: | |||
|     void                create_sla_object_popupmenu(wxMenu*menu); | ||||
|     void                create_part_popupmenu(wxMenu*menu); | ||||
|     void                create_instance_popupmenu(wxMenu*menu); | ||||
|     void                create_default_popupmenu(wxMenu *menu); | ||||
|     wxMenu*             create_settings_popupmenu(wxMenu *parent_menu); | ||||
|     void                create_freq_settings_popupmenu(wxMenu *parent_menu, const bool is_object_settings = true); | ||||
| 
 | ||||
|  | @ -248,6 +250,7 @@ public: | |||
|     void                load_subobject(ModelVolumeType type); | ||||
|     void                load_part(ModelObject* model_object, std::vector<std::pair<wxString, bool>> &volumes_info, ModelVolumeType type); | ||||
| 	void                load_generic_subobject(const std::string& type_name, const ModelVolumeType type); | ||||
|     void                load_shape_object(const std::string &type_name); | ||||
|     void                del_object(const int obj_idx); | ||||
|     void                del_subobject_item(wxDataViewItem& item); | ||||
|     void                del_settings_from_config(const wxDataViewItem& parent_item); | ||||
|  | @ -362,7 +365,7 @@ private: | |||
| //    void OnChar(wxKeyEvent& event);
 | ||||
| #endif /* __WXOSX__ */ | ||||
|     void OnContextMenu(wxDataViewEvent &event); | ||||
|     void list_manipulation(); | ||||
|     void list_manipulation(bool evt_context_menu = false); | ||||
| 
 | ||||
|     void OnBeginDrag(wxDataViewEvent &event); | ||||
|     void OnDropPossible(wxDataViewEvent &event); | ||||
|  |  | |||
|  | @ -4881,6 +4881,11 @@ GLCanvas3D* Plater::canvas3D() | |||
|     return p->view3D->get_canvas3d(); | ||||
| } | ||||
| 
 | ||||
| BoundingBoxf Plater::bed_shape_bb() const | ||||
| { | ||||
|     return p->bed_shape_bb(); | ||||
| } | ||||
| 
 | ||||
| PrinterTechnology Plater::printer_technology() const | ||||
| { | ||||
|     return p->printer_technology; | ||||
|  |  | |||
|  | @ -225,6 +225,7 @@ public: | |||
|     int get_selected_object_idx(); | ||||
|     bool is_single_full_object_selection() const; | ||||
|     GLCanvas3D* canvas3D(); | ||||
|     BoundingBoxf bed_shape_bb() const; | ||||
| 
 | ||||
|     PrinterTechnology   printer_technology() const; | ||||
|     void                set_printer_technology(PrinterTechnology printer_technology); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri