mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Allow rotation of multiple selected items. Disable auto positioning
This commit is contained in:
		
							parent
							
								
									804758dfed
								
							
						
					
					
						commit
						649dfca8d6
					
				
					 6 changed files with 99 additions and 44 deletions
				
			
		|  | @ -78,7 +78,7 @@ void ArrangeJob::prepare_all() { | |||
|     for (ModelObject *obj: m_plater->model().objects) | ||||
|         for (ModelInstance *mi : obj->instances) { | ||||
|             ArrangePolygons & cont = mi->printable ? m_selected : m_unprintable; | ||||
|             cont.emplace_back(get_arrange_poly(PtrWrapper{mi}, m_plater)); | ||||
|             cont.emplace_back(get_arrange_poly(mi, m_plater)); | ||||
|         } | ||||
| 
 | ||||
|     if (auto wti = get_wipe_tower_arrangepoly(*m_plater)) | ||||
|  | @ -111,7 +111,7 @@ void ArrangeJob::prepare_selected() { | |||
|          | ||||
|         for (size_t i = 0; i < inst_sel.size(); ++i) { | ||||
|             ArrangePolygon &&ap = | ||||
|                 get_arrange_poly(PtrWrapper{mo->instances[i]}, m_plater); | ||||
|                 get_arrange_poly(mo->instances[i], m_plater); | ||||
| 
 | ||||
|             ArrangePolygons &cont = mo->instances[i]->printable ? | ||||
|                         (inst_sel[i] ? m_selected : | ||||
|  | @ -161,12 +161,7 @@ void ArrangeJob::process() | |||
| { | ||||
|     static const auto arrangestr = _(L("Arranging")); | ||||
| 
 | ||||
|     const GLCanvas3D::ArrangeSettings &settings = | ||||
|         static_cast<const GLCanvas3D*>(m_plater->canvas3D())->get_arrange_settings(); | ||||
| 
 | ||||
|     arrangement::ArrangeParams params; | ||||
|     params.allow_rotations  = settings.enable_rotation; | ||||
|     params.min_obj_distance = scaled(settings.distance); | ||||
|     arrangement::ArrangeParams params = get_arrange_params(m_plater); | ||||
| 
 | ||||
|     auto count = unsigned(m_selected.size() + m_unprintable.size()); | ||||
|     Points bedpts = get_bed_shape(*m_plater->config()); | ||||
|  | @ -235,4 +230,23 @@ double bed_stride(const Plater *plater) { | |||
|     return scaled<double>((1. + LOGICAL_BED_GAP) * bedwidth); | ||||
| } | ||||
| 
 | ||||
| template<> | ||||
| arrangement::ArrangePolygon get_arrange_poly(ModelInstance *inst, | ||||
|                                              const Plater * plater) | ||||
| { | ||||
|     return get_arrange_poly(PtrWrapper{inst}, plater); | ||||
| } | ||||
| 
 | ||||
| arrangement::ArrangeParams get_arrange_params(Plater *p) | ||||
| { | ||||
|     const GLCanvas3D::ArrangeSettings &settings = | ||||
|         static_cast<const GLCanvas3D*>(p->canvas3D())->get_arrange_settings(); | ||||
| 
 | ||||
|     arrangement::ArrangeParams params; | ||||
|     params.allow_rotations  = settings.enable_rotation; | ||||
|     params.min_obj_distance = scaled(settings.distance); | ||||
| 
 | ||||
|     return params; | ||||
| } | ||||
| 
 | ||||
| }} // namespace Slic3r::GUI
 | ||||
|  |  | |||
|  | @ -4,7 +4,11 @@ | |||
| #include "PlaterJob.hpp" | ||||
| #include "libslic3r/Arrange.hpp" | ||||
| 
 | ||||
| namespace Slic3r { namespace GUI { | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| class ModelInstance; | ||||
| 
 | ||||
| namespace GUI { | ||||
| 
 | ||||
| class ArrangeJob : public PlaterJob | ||||
| { | ||||
|  | @ -89,6 +93,11 @@ arrangement::ArrangePolygon get_arrange_poly(T obj, const Plater *plater) | |||
|     return ap; | ||||
| } | ||||
| 
 | ||||
| template<> | ||||
| arrangement::ArrangePolygon get_arrange_poly(ModelInstance *inst, | ||||
|                                              const Plater * plater); | ||||
| 
 | ||||
| arrangement::ArrangeParams get_arrange_params(Plater *p); | ||||
| 
 | ||||
| }} // namespace Slic3r::GUI
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,36 +32,59 @@ void RotoptimizeJob::prepare() | |||
|     m_method_id = std::max(size_t(0), std::min(get_methods_count() - 1, m_method_id)); | ||||
| 
 | ||||
|     m_default_print_cfg = wxGetApp().preset_bundle->full_config(); | ||||
| 
 | ||||
|     const auto &sel = m_plater->get_selection().get_content(); | ||||
| 
 | ||||
|     m_selected_object_ids.clear(); | ||||
|     m_selected_object_ids.reserve(sel.size()); | ||||
|     for (auto &[obj_idx, ignore] : sel) | ||||
|         m_selected_object_ids.emplace_back(obj_idx); | ||||
| } | ||||
| 
 | ||||
| void RotoptimizeJob::process() | ||||
| { | ||||
|     int obj_idx = m_plater->get_selected_object_idx(); | ||||
|     if (obj_idx < 0) | ||||
|         return; | ||||
|      | ||||
|     ModelObject *o = m_plater->model().objects[size_t(obj_idx)]; | ||||
| 
 | ||||
|     if (!o) return; | ||||
| 
 | ||||
|     int prev_status = 0; | ||||
|     auto params = | ||||
|         sla::RotOptimizeParams{} | ||||
|             .accuracy(m_accuracy) | ||||
|             .print_config(&m_default_print_cfg) | ||||
|             .statucb([this](int s) { | ||||
|             .statucb([this, &prev_status](int s) | ||||
|         { | ||||
|             if (s > 0 && s < 100) | ||||
|                 update_status(s, _(L("Searching for optimal orientation"))); | ||||
|                 update_status(prev_status + s / m_selected_object_ids.size(), | ||||
|                               _(L("Searching for optimal orientation"))); | ||||
| 
 | ||||
|             return !was_canceled(); | ||||
|         }); | ||||
| 
 | ||||
|     Vec2d r = Methods[m_method_id].findfn(*o, params); | ||||
| 
 | ||||
|     double mindist = 6.0; // FIXME
 | ||||
|     for (ObjRot &objrot : m_selected_object_ids) { | ||||
|         ModelObject *o = m_plater->model().objects[size_t(objrot.idx)]; | ||||
|         if (!o) continue; | ||||
| 
 | ||||
|         if (Methods[m_method_id].findfn) | ||||
|             objrot.rot = Methods[m_method_id].findfn(*o, params); | ||||
| 
 | ||||
|         prev_status += 100 / m_selected_object_ids.size(); | ||||
| 
 | ||||
|         if (was_canceled()) break; | ||||
|     } | ||||
| 
 | ||||
|     update_status(100, was_canceled() ? _(L("Orientation search canceled.")) : | ||||
|                                         _(L("Orientation found."))); | ||||
| } | ||||
| 
 | ||||
| void RotoptimizeJob::finalize() | ||||
| { | ||||
|     if (was_canceled()) return; | ||||
| 
 | ||||
|     for (const ObjRot &objrot : m_selected_object_ids) { | ||||
|         ModelObject *o = m_plater->model().objects[size_t(objrot.idx)]; | ||||
|         if (!o) continue; | ||||
| 
 | ||||
|     if (!was_canceled()) { | ||||
|         for(ModelInstance * oi : o->instances) { | ||||
|             oi->set_rotation({r[X], r[Y], 0.}); | ||||
|             if (objrot.rot) | ||||
|                 oi->set_rotation({objrot.rot->x(), objrot.rot->y(), 0.}); | ||||
| 
 | ||||
|             auto    trmatrix = oi->get_transformation().get_matrix(); | ||||
|             Polygon trchull  = o->convex_hull_2d(trmatrix); | ||||
|  | @ -77,19 +100,13 @@ void RotoptimizeJob::process() | |||
|             oi->set_rotation(rt); | ||||
|         } | ||||
| 
 | ||||
|         m_plater->find_new_position(o->instances, scaled(mindist)); | ||||
| 
 | ||||
|         // Correct the z offset of the object which was corrupted be
 | ||||
|         // the rotation
 | ||||
|         o->ensure_on_bed(); | ||||
| 
 | ||||
| //        m_plater->find_new_position(o->instances);
 | ||||
|     } | ||||
| 
 | ||||
|     update_status(100, was_canceled() ? _(L("Orientation search canceled.")) : | ||||
|                                         _(L("Orientation found."))); | ||||
| } | ||||
| 
 | ||||
| void RotoptimizeJob::finalize() | ||||
| { | ||||
|     if (!was_canceled()) | ||||
|         m_plater->update(); | ||||
|      | ||||
|  |  | |||
|  | @ -19,7 +19,9 @@ class RotoptimizeJob : public PlaterJob | |||
| 
 | ||||
|     static inline const FindMethod Methods[] = { | ||||
|         { L("Best misalignment"), sla::find_best_misalignment_rotation }, | ||||
|         { L("Least supports"), sla::find_least_supports_rotation } | ||||
|         { L("Least supports"), sla::find_least_supports_rotation }, | ||||
|         // Just a min area bounding box that is done for all methods anyway.
 | ||||
|         { L("Z axis only"), nullptr } | ||||
|     }; | ||||
| 
 | ||||
|     size_t m_method_id = 0; | ||||
|  | @ -27,6 +29,15 @@ class RotoptimizeJob : public PlaterJob | |||
| 
 | ||||
|     DynamicPrintConfig m_default_print_cfg; | ||||
| 
 | ||||
|     struct ObjRot | ||||
|     { | ||||
|         size_t               idx; | ||||
|         std::optional<Vec2d> rot; | ||||
|         ObjRot(size_t id): idx{id}, rot{} {} | ||||
|     }; | ||||
| 
 | ||||
|     std::vector<ObjRot> m_selected_object_ids; | ||||
| 
 | ||||
| protected: | ||||
| 
 | ||||
|     void prepare() override; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros