mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 12:11:15 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/Slic3r into objects_centering
This commit is contained in:
		
						commit
						9a69305367
					
				
					 7 changed files with 134 additions and 45 deletions
				
			
		|  | @ -510,15 +510,14 @@ GLCanvas3D::Bed::EType GLCanvas3D::Bed::_detect_type() const | |||
| 				{ | ||||
| 					if ((curr->vendor != nullptr) && (curr->vendor->name == "Prusa Research")) | ||||
| 					{ | ||||
| 						if (boost::contains(curr->name, "MK2")) | ||||
| 						{ | ||||
| 							type = MK2; | ||||
| 							break; | ||||
| 						} | ||||
| 						else if (boost::contains(curr->name, "MK3")) | ||||
| 						if (boost::contains(curr->name, "MK3") || boost::contains(curr->name, "MK2.5")) | ||||
| 						{ | ||||
| 							type = MK3; | ||||
| 							break; | ||||
| 						} else if (boost::contains(curr->name, "MK2")) | ||||
| 						{ | ||||
| 							type = MK2; | ||||
| 							break; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
|  | @ -587,8 +586,14 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const | |||
|     if (theta <= 90.0f) | ||||
|     { | ||||
|         filename = model_path + "_bed.stl"; | ||||
|         if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, useVBOs)) | ||||
|             m_model.center_around(m_bounding_box.center() - Vec3d(0.0, 0.0, 0.1 + 0.5 * m_model.get_bounding_box().size()(2))); | ||||
|         if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, useVBOs)) { | ||||
|             Vec3d offset = m_bounding_box.center() - Vec3d(0.0, 0.0, 0.1 + 0.5 * m_model.get_bounding_box().size()(2)); | ||||
|             if (key == "mk2") | ||||
|                 offset.y() += 15. / 2.; | ||||
|             else if (key == "mk3") | ||||
|                 offset += Vec3d(0., (19. - 8.) / 2., 2.); | ||||
|             m_model.center_around(offset); | ||||
|         } | ||||
| 
 | ||||
|         if (!m_model.get_filename().empty()) | ||||
|         { | ||||
|  | @ -5196,7 +5201,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|                         if (m_volumes.volumes[m_hover_volume_id]->hover && !m_volumes.volumes[m_hover_volume_id]->is_wipe_tower) | ||||
|                         { | ||||
|                             // forces the selection of the volume
 | ||||
|                             m_selection.add(m_hover_volume_id); | ||||
|                             if (!m_selection.is_multiple_full_instance()) | ||||
|                                 m_selection.add(m_hover_volume_id); | ||||
|                             m_gizmos.update_on_off_state(m_selection); | ||||
|                             post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); | ||||
|                             _update_gizmos_data(); | ||||
|  |  | |||
|  | @ -51,6 +51,7 @@ ObjectList::ObjectList(wxWindow* parent) : | |||
|     create_object_popupmenu(&m_menu_object); | ||||
|     create_part_popupmenu(&m_menu_part); | ||||
|     create_sla_object_popupmenu(&m_menu_sla_object); | ||||
|     create_instance_popupmenu(&m_menu_instance); | ||||
| 
 | ||||
|     // describe control behavior 
 | ||||
|     Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxEvent& event) { | ||||
|  | @ -400,15 +401,28 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) | |||
| 
 | ||||
| void ObjectList::show_context_menu() | ||||
| { | ||||
|     if (multiple_selection() && selected_instances_of_same_object()) | ||||
|     { | ||||
|         wxGetApp().plater()->PopupMenu(&m_menu_instance); | ||||
| 
 | ||||
|         wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { | ||||
|             evt.Enable(can_split_instances()); }, m_menu_item_split_instances->GetId()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const auto item = GetSelection(); | ||||
|     if (item) | ||||
|     { | ||||
|         if (!(m_objects_model->GetItemType(item) & (itObject | itVolume))) | ||||
|         const ItemType type = m_objects_model->GetItemType(item); | ||||
|         if (!(type & (itObject | itVolume | itInstance))) | ||||
|             return; | ||||
|         wxMenu* menu = m_objects_model->GetParent(item) != wxDataViewItem(0) ? &m_menu_part : | ||||
| 
 | ||||
|         wxMenu* menu = type & itInstance ? &m_menu_instance : | ||||
|                        m_objects_model->GetParent(item) != wxDataViewItem(0) ? &m_menu_part : | ||||
|                        wxGetApp().plater()->printer_technology() == ptFFF ? &m_menu_object : &m_menu_sla_object; | ||||
| 
 | ||||
|         append_menu_item_settings(menu); | ||||
|         if (!(type & itInstance)) | ||||
|             append_menu_item_settings(menu); | ||||
| 
 | ||||
|         wxGetApp().plater()->PopupMenu(menu); | ||||
| 
 | ||||
|  | @ -443,9 +457,11 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event) | |||
| { | ||||
|     const wxDataViewItem item(event.GetItem()); | ||||
| 
 | ||||
|     // only allow drags for item, not containers
 | ||||
|     if (multiple_selection() || GetSelection()!=item ||  | ||||
|         m_objects_model->GetParent(item) == wxDataViewItem(0)) { | ||||
|     const bool mult_sel = multiple_selection(); | ||||
| 
 | ||||
|     if (mult_sel && !selected_instances_of_same_object() || | ||||
|         !mult_sel && (GetSelection() != item || | ||||
|         m_objects_model->GetParent(item) == wxDataViewItem(0) ) ) { | ||||
|         event.Veto(); | ||||
|         return; | ||||
|     } | ||||
|  | @ -456,7 +472,17 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event) | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     m_dragged_data.init(m_objects_model->GetObjectIdByItem(item),  | ||||
|     if (mult_sel) | ||||
|     { | ||||
|         m_dragged_data.init(m_objects_model->GetObjectIdByItem(item),type); | ||||
|         std::set<int>& sub_obj_idxs = m_dragged_data.inst_idxs(); | ||||
|         wxDataViewItemArray sels; | ||||
|         GetSelections(sels); | ||||
|         for (auto sel : sels ) | ||||
|             sub_obj_idxs.insert(m_objects_model->GetInstanceIdByItem(sel)); | ||||
|     } | ||||
|     else  | ||||
|         m_dragged_data.init(m_objects_model->GetObjectIdByItem(item),  | ||||
|                         type&itVolume ? m_objects_model->GetVolumeIdByItem(item) : | ||||
|                                         m_objects_model->GetInstanceIdByItem(item),  | ||||
|                         type); | ||||
|  | @ -507,7 +533,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event) | |||
| 
 | ||||
|     if (m_dragged_data.type() == itInstance) | ||||
|     { | ||||
|         instance_to_separated_object(m_dragged_data.obj_idx(), m_dragged_data.sub_obj_idx()); | ||||
|         instances_to_separated_object(m_dragged_data.obj_idx(), m_dragged_data.inst_idxs()); | ||||
|         m_dragged_data.clear(); | ||||
|         return; | ||||
|     } | ||||
|  | @ -759,6 +785,12 @@ wxMenuItem* ObjectList::append_menu_item_change_type(wxMenu* menu) | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu) | ||||
| { | ||||
|     return append_menu_item(menu, wxID_ANY, _(L("Set as a Separated Object")), "", | ||||
|         [this](wxCommandEvent&) { split_instances(); }, "", menu); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::create_object_popupmenu(wxMenu *menu) | ||||
| { | ||||
|     append_menu_items_add_volume(menu); | ||||
|  | @ -787,6 +819,11 @@ void ObjectList::create_part_popupmenu(wxMenu *menu) | |||
|     menu->AppendSeparator(); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::create_instance_popupmenu(wxMenu*menu) | ||||
| { | ||||
|     m_menu_item_split_instances = append_menu_item_instance_to_object(menu); | ||||
| } | ||||
| 
 | ||||
| wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu) | ||||
| { | ||||
|     wxMenu *menu = new wxMenu; | ||||
|  | @ -1138,6 +1175,27 @@ bool ObjectList::is_splittable() | |||
|     return splittable; | ||||
| } | ||||
| 
 | ||||
| bool ObjectList::selected_instances_of_same_object() | ||||
| { | ||||
|     wxDataViewItemArray sels; | ||||
|     GetSelections(sels); | ||||
| 
 | ||||
|     const int obj_idx = m_objects_model->GetObjectIdByItem(sels.front()); | ||||
| 
 | ||||
|     for (auto item : sels) { | ||||
|         if (! (m_objects_model->GetItemType(item) & itInstance) || | ||||
|             obj_idx != m_objects_model->GetObjectIdByItem(item)) | ||||
|             return false; | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| bool ObjectList::can_split_instances() | ||||
| { | ||||
|     const GLCanvas3D::Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); | ||||
|     return selection.is_multiple_full_instance() || selection.is_single_full_instance(); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::part_settings_changed() | ||||
| { | ||||
|     m_part_settings_changed = true; | ||||
|  | @ -1441,7 +1499,7 @@ bool ObjectList::multiple_selection() const | |||
| 
 | ||||
| void ObjectList::update_selections() | ||||
| { | ||||
|     auto& selection = wxGetApp().plater()->canvas3D()->get_selection(); | ||||
|     const GLCanvas3D::Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); | ||||
|     wxDataViewItemArray sels; | ||||
| 
 | ||||
|     // We doesn't update selection if SettingsItem for the current object/part is selected
 | ||||
|  | @ -1527,7 +1585,7 @@ void ObjectList::update_selections() | |||
| 
 | ||||
| void ObjectList::update_selections_on_canvas() | ||||
| { | ||||
|     auto& selection = wxGetApp().plater()->canvas3D()->get_selection(); | ||||
|     GLCanvas3D::Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); | ||||
| 
 | ||||
|     const int sel_cnt = GetSelectedItemsCount(); | ||||
|     if (sel_cnt == 0) { | ||||
|  | @ -1751,23 +1809,41 @@ void ObjectList::update_settings_items() | |||
|     UnselectAll(); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::instance_to_separated_object(const int obj_idx, const int inst_idx) | ||||
| void ObjectList::instances_to_separated_object(const int obj_idx, const std::set<int>& inst_idxs) | ||||
| { | ||||
|     // create new object from selected instance  
 | ||||
|     ModelObject* model_object = (*m_objects)[obj_idx]->get_model()->add_object(*(*m_objects)[obj_idx]); | ||||
|     for (int i = model_object->instances.size() - 1; i >= 0; i--) | ||||
|     for (int inst_idx = model_object->instances.size() - 1; inst_idx >= 0; inst_idx--) | ||||
|     { | ||||
|         if (i == inst_idx) | ||||
|         if (find(inst_idxs.begin(), inst_idxs.end(), inst_idx) != inst_idxs.end()) | ||||
|             continue; | ||||
|         model_object->delete_instance(i); | ||||
|         model_object->delete_instance(inst_idx); | ||||
|     } | ||||
| 
 | ||||
|     // Add new object to the object_list
 | ||||
|     add_object_to_list(m_objects->size() - 1); | ||||
| 
 | ||||
|     // delete selected instance from the object
 | ||||
|     del_subobject_from_object(obj_idx, inst_idx, itInstance); | ||||
|     delete_instance_from_list(obj_idx, inst_idx); | ||||
|     for (std::set<int>::const_reverse_iterator it = inst_idxs.rbegin(); it != inst_idxs.rend(); ++it) | ||||
|     { | ||||
|         // delete selected instance from the object
 | ||||
|         del_subobject_from_object(obj_idx, *it, itInstance); | ||||
|         delete_instance_from_list(obj_idx, *it); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ObjectList::split_instances() | ||||
| { | ||||
|     const GLCanvas3D::Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); | ||||
|     const int obj_idx = selection.get_object_idx(); | ||||
|     if (obj_idx == -1) | ||||
|         return; | ||||
| 
 | ||||
|     const int inst_idx = selection.get_instance_idx(); | ||||
|     const std::set<int> inst_idxs = inst_idx < 0 ? | ||||
|                                     selection.get_instance_idxs() : | ||||
|                                     std::set<int>{ inst_idx }; | ||||
| 
 | ||||
|     instances_to_separated_object(obj_idx, inst_idxs); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::ItemValueChanged(wxDataViewEvent &event) | ||||
|  |  | |||
|  | @ -58,23 +58,34 @@ class ObjectList : public wxDataViewCtrl | |||
|     { | ||||
|         void init(const int obj_idx, const int subobj_idx, const ItemType type) { | ||||
|             m_obj_idx = obj_idx; | ||||
|             m_subobj_idx = subobj_idx; | ||||
|             m_type = type; | ||||
|             if (m_type&itVolume) | ||||
|                 m_vol_idx = subobj_idx; | ||||
|             else | ||||
|                 m_inst_idxs.insert(subobj_idx); | ||||
|         } | ||||
| 
 | ||||
|         void init(const int obj_idx, const ItemType type) { | ||||
|             m_obj_idx = obj_idx; | ||||
|             m_type = type; | ||||
|         } | ||||
| 
 | ||||
|         void clear() { | ||||
|             m_obj_idx = -1; | ||||
|             m_subobj_idx = -1; | ||||
|             m_vol_idx = -1; | ||||
|             m_inst_idxs.clear(); | ||||
|             m_type = itUndef; | ||||
|         } | ||||
| 
 | ||||
|         int obj_idx() const  { return m_obj_idx; } | ||||
|         int sub_obj_idx() const  { return m_subobj_idx; } | ||||
|         int sub_obj_idx() const  { return m_vol_idx; } | ||||
|         ItemType type() const { return m_type; } | ||||
|         std::set<int>& inst_idxs() { return m_inst_idxs; } | ||||
| 
 | ||||
|     private: | ||||
|         int m_obj_idx = -1; | ||||
|         int m_subobj_idx = -1; | ||||
|         int m_vol_idx = -1; | ||||
|         std::set<int> m_inst_idxs{}; | ||||
|         ItemType m_type = itUndef; | ||||
| 
 | ||||
|     } m_dragged_data; | ||||
|  | @ -96,9 +107,11 @@ class ObjectList : public wxDataViewCtrl | |||
|     wxMenu      m_menu_object; | ||||
|     wxMenu      m_menu_part; | ||||
|     wxMenu      m_menu_sla_object; | ||||
|     wxMenu      m_menu_instance; | ||||
|     wxMenuItem* m_menu_item_split { nullptr }; | ||||
|     wxMenuItem* m_menu_item_split_part { nullptr }; | ||||
|     wxMenuItem* m_menu_item_settings { nullptr }; | ||||
|     wxMenuItem* m_menu_item_split_instances { nullptr }; | ||||
| 
 | ||||
|     std::vector<wxBitmap*> m_bmp_vector; | ||||
| 
 | ||||
|  | @ -153,9 +166,11 @@ public: | |||
|     wxMenuItem*         append_menu_item_split(wxMenu* menu); | ||||
|     wxMenuItem*         append_menu_item_settings(wxMenu* menu); | ||||
|     wxMenuItem*         append_menu_item_change_type(wxMenu* menu); | ||||
|     wxMenuItem*         append_menu_item_instance_to_object(wxMenu* menu); | ||||
|     void                create_object_popupmenu(wxMenu *menu); | ||||
|     void                create_sla_object_popupmenu(wxMenu*menu); | ||||
|     void                create_part_popupmenu(wxMenu*menu); | ||||
|     void                create_instance_popupmenu(wxMenu*menu); | ||||
|     wxMenu*             create_settings_popupmenu(wxMenu *parent_menu); | ||||
| 
 | ||||
|     void                update_opt_keys(t_config_option_keys& t_optopt_keys); | ||||
|  | @ -171,6 +186,8 @@ public: | |||
|     void                split(); | ||||
|     bool                get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume); | ||||
|     bool                is_splittable(); | ||||
|     bool                selected_instances_of_same_object(); | ||||
|     bool                can_split_instances(); | ||||
| 
 | ||||
|     wxPoint             get_mouse_position_in_control(); | ||||
|     wxBoxSizer*         get_sizer() {return  m_sizer;} | ||||
|  | @ -227,7 +244,8 @@ public: | |||
|     bool has_multi_part_objects(); | ||||
|     void update_settings_items(); | ||||
| 
 | ||||
|     void instance_to_separated_object(const int obj_idx, const int inst_idx); | ||||
|     void instances_to_separated_object(const int obj_idx, const std::set<int>& inst_idx); | ||||
|     void split_instances(); | ||||
| 
 | ||||
| private: | ||||
|     void OnChar(wxKeyEvent& event); | ||||
|  |  | |||
|  | @ -2381,8 +2381,7 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ | |||
|             [this](wxCommandEvent&) { q->set_number_of_copies(); }, "textfield.png"); | ||||
| 
 | ||||
|         menu->AppendSeparator(); | ||||
|         wxMenuItem* item_instance_to_object = append_menu_item(menu, wxID_ANY, _(L("Set as a Separated Object")) + dots, _(L("Set an Instance as a Separate Object")), | ||||
|             [this](wxCommandEvent&) { q->instance_to_separated_object(); }, ""); | ||||
|         wxMenuItem* item_instance_to_object = sidebar->obj_list()->append_menu_item_instance_to_object(menu); | ||||
| 
 | ||||
|         if (q != nullptr) | ||||
|         { | ||||
|  | @ -2792,16 +2791,6 @@ void Plater::set_number_of_copies(/*size_t num*/) | |||
|         decrease_instances(-diff); | ||||
| } | ||||
| 
 | ||||
| void Plater::instance_to_separated_object() | ||||
| { | ||||
|     const int obj_idx = p->get_selected_object_idx(); | ||||
|     const int inst_idx = p->get_selection().get_instance_idx(); | ||||
|     if (obj_idx == -1 || inst_idx == -1) | ||||
|         return; | ||||
| 
 | ||||
|     sidebar().obj_list()->instance_to_separated_object(obj_idx, inst_idx); | ||||
| } | ||||
| 
 | ||||
| bool Plater::is_selection_empty() const | ||||
| { | ||||
|     return p->get_selection().is_empty(); | ||||
|  |  | |||
|  | @ -136,7 +136,6 @@ public: | |||
|     void increase_instances(size_t num = 1); | ||||
|     void decrease_instances(size_t num = 1); | ||||
|     void set_number_of_copies(/*size_t num*/); | ||||
|     void instance_to_separated_object(); | ||||
|     bool is_selection_empty() const; | ||||
| 
 | ||||
|     void cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false); | ||||
|  |  | |||
|  | @ -406,7 +406,7 @@ void PrusaObjectDataViewModelNode::set_object_action_icon() { | |||
| 	m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("add_object.png")), wxBITMAP_TYPE_PNG); | ||||
| } | ||||
| void  PrusaObjectDataViewModelNode::set_part_action_icon() { | ||||
| 	m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG); | ||||
| 	m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var(m_type == itVolume ? "cog.png" : "brick_go.png")), wxBITMAP_TYPE_PNG); | ||||
| } | ||||
| 
 | ||||
| Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr; | ||||
|  |  | |||
|  | @ -275,6 +275,7 @@ public: | |||
|         else if (type == itInstance) { | ||||
|             m_idx = parent->GetChildCount(); | ||||
|             m_name = wxString::Format("Instance_%d", m_idx+1); | ||||
|             set_part_action_icon(); | ||||
|         } | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri