mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
		
						commit
						077d4aa3d7
					
				
					 7 changed files with 114 additions and 9 deletions
				
			
		|  | @ -410,6 +410,8 @@ public: | |||
|     BoundingBoxf3        transformed_convex_hull_bounding_box(const Transform3d &trafo) const; | ||||
|     // caching variant
 | ||||
|     const BoundingBoxf3& transformed_convex_hull_bounding_box() const; | ||||
|     // convex hull
 | ||||
|     const TriangleMesh*  convex_hull() const { return m_convex_hull.get(); } | ||||
| 
 | ||||
|     bool                empty() const { return this->indexed_vertex_array.empty(); } | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,28 @@ namespace Slic3r | |||
| namespace GUI | ||||
| { | ||||
| 
 | ||||
| 
 | ||||
| // Helper function to be used by drop to bed button. Returns lowest point of this
 | ||||
| // volume in world coordinate system.
 | ||||
| static double get_volume_min_z(const GLVolume* volume) | ||||
| { | ||||
|     const Transform3f& world_matrix = volume->world_matrix().cast<float>(); | ||||
| 
 | ||||
|     // need to get the ModelVolume pointer
 | ||||
|     const ModelObject* mo = wxGetApp().model_objects()->at(volume->composite_id.object_id); | ||||
|     const ModelVolume* mv = mo->volumes[volume->composite_id.volume_id]; | ||||
|     const TriangleMesh& hull = mv->get_convex_hull(); | ||||
| 
 | ||||
|     float min_z = std::numeric_limits<float>::max(); | ||||
|     for (const stl_facet& facet : hull.stl.facet_start) { | ||||
|         for (int i = 0; i < 3; ++ i) | ||||
|             min_z = std::min(min_z, Vec3f::UnitZ().dot(world_matrix * facet.vertex[i])); | ||||
|     } | ||||
|     return min_z; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| static wxBitmapComboBox* create_word_local_combo(wxWindow *parent) | ||||
| { | ||||
|     wxSize size(15 * wxGetApp().em_unit(), -1); | ||||
|  | @ -185,7 +207,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : | |||
|         unsigned int axis_idx = (axis[0] - 'x'); // 0, 1 or 2
 | ||||
| 
 | ||||
|         // We will add a button to toggle mirroring to each axis:
 | ||||
|         auto mirror_button = [=](wxWindow* parent) { | ||||
|         auto mirror_button = [this, mirror_btn_width, axis_idx, &label](wxWindow* parent) { | ||||
|             wxSize btn_size(em_unit(parent) * mirror_btn_width, em_unit(parent) * mirror_btn_width); | ||||
|             auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off.png", wxEmptyString, btn_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW); | ||||
|             btn->SetToolTip(wxString::Format(_(L("Toggle %s axis mirroring")), label)); | ||||
|  | @ -195,7 +217,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : | |||
|             auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|             sizer->Add(btn); | ||||
| 
 | ||||
|             btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { | ||||
|             btn->Bind(wxEVT_BUTTON, [this, axis_idx](wxCommandEvent &e) { | ||||
|                 Axis axis = (Axis)(axis_idx + X); | ||||
|                 if (m_mirror_buttons[axis_idx].second == mbHidden) | ||||
|                     return; | ||||
|  | @ -258,13 +280,13 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : | |||
|                 return btn; | ||||
|             }; | ||||
|             // Add reset scale button
 | ||||
|             auto reset_scale_button = [=](wxWindow* parent) { | ||||
|             auto reset_scale_button = [this](wxWindow* parent) { | ||||
|                 auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo")); | ||||
|                 btn->SetToolTip(_(L("Reset scale"))); | ||||
|                 m_reset_scale_button = btn; | ||||
|                 auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|                 sizer->Add(btn, wxBU_EXACTFIT); | ||||
|                 btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { | ||||
|                 btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { | ||||
|                     change_scale_value(0, 100.); | ||||
|                     change_scale_value(1, 100.); | ||||
|                     change_scale_value(2, 100.); | ||||
|  | @ -275,13 +297,13 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : | |||
|         } | ||||
|         else if (option_name == "Rotation") { | ||||
|             // Add reset rotation button
 | ||||
|             auto reset_rotation_button = [=](wxWindow* parent) { | ||||
|             auto reset_rotation_button = [this](wxWindow* parent) { | ||||
|                 auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo")); | ||||
|                 btn->SetToolTip(_(L("Reset rotation"))); | ||||
|                 m_reset_rotation_button = btn; | ||||
|                 auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|                 sizer->Add(btn, wxBU_EXACTFIT); | ||||
|                 btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { | ||||
|                 btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { | ||||
|                     GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); | ||||
|                     Selection& selection = canvas->get_selection(); | ||||
| 
 | ||||
|  | @ -310,6 +332,34 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : | |||
|             }; | ||||
|             line.append_widget(reset_rotation_button); | ||||
|         } | ||||
|         else if (option_name == "Position") { | ||||
|             // Add drop to bed button
 | ||||
|             auto drop_to_bed_button = [=](wxWindow* parent) { | ||||
|                 auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "drop_to_bed.png")); | ||||
|                 btn->SetToolTip(_(L("Drop to bed"))); | ||||
|                 m_drop_to_bed_button = btn; | ||||
|                 auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|                 sizer->Add(btn, wxBU_EXACTFIT); | ||||
|                 btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { | ||||
|                     // ???
 | ||||
|                     GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); | ||||
|                     Selection& selection = canvas->get_selection(); | ||||
| 
 | ||||
|                     if (selection.is_single_volume() || selection.is_single_modifier()) { | ||||
|                         const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); | ||||
| 
 | ||||
|                         const Geometry::Transformation& instance_trafo = volume->get_instance_transformation(); | ||||
|                         Vec3d diff = m_cache.position - instance_trafo.get_matrix(true).inverse() * Vec3d(0., 0., get_volume_min_z(volume)); | ||||
| 
 | ||||
|                         change_position_value(0, diff.x()); | ||||
|                         change_position_value(1, diff.y()); | ||||
|                         change_position_value(2, diff.z()); | ||||
|                     } | ||||
|                 }); | ||||
|             return sizer; | ||||
|             }; | ||||
|             line.append_widget(drop_to_bed_button); | ||||
|         } | ||||
|         // Add empty bmp (Its size have to be equal to PrusaLockButton) in front of "Size" option to label alignment
 | ||||
|         else if (option_name == "Size") { | ||||
|             line.near_label_widget = [this](wxWindow* parent) { | ||||
|  | @ -536,11 +586,13 @@ void ObjectManipulation::update_reset_buttons_visibility() | |||
| 
 | ||||
|     bool show_rotation = false; | ||||
|     bool show_scale = false; | ||||
|     bool show_drop_to_bed = false; | ||||
| 
 | ||||
|     if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) { | ||||
|         const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); | ||||
|         Vec3d rotation; | ||||
|         Vec3d scale; | ||||
|         double min_z = 0.; | ||||
| 
 | ||||
|         if (selection.is_single_full_instance()) { | ||||
|             rotation = volume->get_instance_rotation(); | ||||
|  | @ -549,14 +601,17 @@ void ObjectManipulation::update_reset_buttons_visibility() | |||
|         else { | ||||
|             rotation = volume->get_volume_rotation(); | ||||
|             scale = volume->get_volume_scaling_factor(); | ||||
|             min_z = get_volume_min_z(volume); | ||||
|         } | ||||
|         show_rotation = !rotation.isApprox(Vec3d::Zero()); | ||||
|         show_scale = !scale.isApprox(Vec3d::Ones()); | ||||
|         show_drop_to_bed = (std::abs(min_z) > EPSILON); | ||||
|     } | ||||
| 
 | ||||
|     wxGetApp().CallAfter([this, show_rotation, show_scale]{ | ||||
|     wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed]{ | ||||
|         m_reset_rotation_button->Show(show_rotation); | ||||
|         m_reset_scale_button->Show(show_scale); | ||||
|         m_drop_to_bed_button->Show(show_drop_to_bed); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
|  | @ -869,6 +924,7 @@ void ObjectManipulation::msw_rescale() | |||
|     m_mirror_bitmap_hidden.msw_rescale(); | ||||
|     m_reset_scale_button->msw_rescale(); | ||||
|     m_reset_rotation_button->msw_rescale(); | ||||
|     m_drop_to_bed_button->msw_rescale(); | ||||
| 
 | ||||
|     get_og()->msw_rescale(); | ||||
| } | ||||
|  |  | |||
|  | @ -56,6 +56,7 @@ class ObjectManipulation : public OG_Settings | |||
|     // Non-owning pointers to the reset buttons, so we can hide and show them.
 | ||||
|     ScalableButton* m_reset_scale_button = nullptr; | ||||
|     ScalableButton* m_reset_rotation_button = nullptr; | ||||
|     ScalableButton* m_drop_to_bed_button = nullptr; | ||||
| 
 | ||||
|     // Mirroring buttons and their current state
 | ||||
|     enum MirrorButtonState { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri