mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Method selection implemented
This commit is contained in:
		
							parent
							
								
									4eb13a407f
								
							
						
					
					
						commit
						0194094afa
					
				
					 6 changed files with 181 additions and 18 deletions
				
			
		|  | @ -92,7 +92,7 @@ Transform3f to_transform3f(const XYRotation &rot) | |||
| 
 | ||||
| } // namespace
 | ||||
| 
 | ||||
| Vec2d find_best_rotation(const SLAPrintObject &   po, | ||||
| Vec2d find_best_misalignment_rotation(const SLAPrintObject &   po, | ||||
|                                       float                    accuracy, | ||||
|                                       std::function<bool(int)> statuscb) | ||||
| { | ||||
|  | @ -156,12 +156,4 @@ Vec2d find_best_rotation(const SLAPrintObject &   po, | |||
|     return {rot[0], rot[1]}; | ||||
| } | ||||
| 
 | ||||
| double get_model_supportedness(const SLAPrintObject &po, const Transform3f &tr) | ||||
| { | ||||
|     TriangleMesh mesh = po.model_object()->raw_mesh(); | ||||
|     mesh.require_shared_vertices(); | ||||
| 
 | ||||
|     return get_model_supportedness(mesh, tr); | ||||
| } | ||||
| 
 | ||||
| }} // namespace Slic3r::sla
 | ||||
|  |  | |||
|  | @ -9,9 +9,12 @@ | |||
| namespace Slic3r { | ||||
| 
 | ||||
| class SLAPrintObject; | ||||
| class TriangleMesh; | ||||
| 
 | ||||
| namespace sla { | ||||
| 
 | ||||
| using RotOptimizeStatusCB = std::function<bool(int)>; | ||||
| 
 | ||||
| /**
 | ||||
|   * The function should find the best rotation for SLA upside down printing. | ||||
|   * | ||||
|  | @ -28,14 +31,13 @@ namespace sla { | |||
|   * | ||||
|   * @return Returns the rotations around each axis (x, y, z) | ||||
|   */ | ||||
| Vec2d find_best_rotation( | ||||
| Vec2d find_best_misalignment_rotation( | ||||
|         const SLAPrintObject& modelobj, | ||||
|         float accuracy = 1.0f, | ||||
|         std::function<bool(int)> statuscb = [] (int) { return true; } | ||||
|         RotOptimizeStatusCB statuscb = [] (int) { return true; } | ||||
|         ); | ||||
| 
 | ||||
| double get_model_supportedness(const SLAPrintObject &mesh, | ||||
|                                const Transform3f & tr); | ||||
| 
 | ||||
| 
 | ||||
| } // namespace sla
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -7,9 +7,10 @@ | |||
| 
 | ||||
| #include "slic3r/GUI/GUI_App.hpp" | ||||
| #include "slic3r/GUI/GUI.hpp" | ||||
| #include "slic3r/GUI/Plater.hpp" | ||||
| #include "libslic3r/PresetBundle.hpp" | ||||
| 
 | ||||
| #include "libslic3r/SLA/Rotfinder.hpp" | ||||
| #include "slic3r/GUI/Jobs/RotoptimizeJob.hpp" | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
|  | @ -204,6 +205,23 @@ void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limi | |||
| { | ||||
|     if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) | ||||
|         return; | ||||
| 
 | ||||
|     RotoptimzeWindow popup{m_imgui, m_rotoptimizewin_state, {x, y, bottom_limit}}; | ||||
| } | ||||
| 
 | ||||
| void GLGizmoRotate3D::load_rotoptimize_state() | ||||
| { | ||||
|     std::string accuracy_str = | ||||
|         wxGetApp().app_config->get("rotoptimize", "accuracy"); | ||||
| 
 | ||||
|     std::string method_str = | ||||
|         wxGetApp().app_config->get("rotoptimize", "method_id"); | ||||
| 
 | ||||
|     if (!accuracy_str.empty()) | ||||
|         m_rotoptimizewin_state.accuracy = std::stof(accuracy_str); | ||||
| 
 | ||||
|     if (!method_str.empty()) | ||||
|         m_rotoptimizewin_state.method_id = std::stoi(method_str); | ||||
| } | ||||
| 
 | ||||
| void GLGizmoRotate::render_circle() const | ||||
|  | @ -436,6 +454,9 @@ GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_fil | |||
|     { | ||||
|         m_gizmos[i].set_group_id(i); | ||||
|     } | ||||
| 
 | ||||
|     std::cout << "Load rotopt state" << std::endl; | ||||
|     load_rotoptimize_state(); | ||||
| } | ||||
| 
 | ||||
| bool GLGizmoRotate3D::on_init() | ||||
|  | @ -492,5 +513,57 @@ void GLGizmoRotate3D::on_render() const | |||
|         m_gizmos[Z].render(); | ||||
| } | ||||
| 
 | ||||
| const char * GLGizmoRotate3D::RotoptimzeWindow::options[RotoptimizeJob::get_methods_count()]; | ||||
| bool GLGizmoRotate3D::RotoptimzeWindow::options_valid = false; | ||||
| 
 | ||||
| GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper *   imgui, | ||||
|                                                     State &          state, | ||||
|                                                     const Alignment &alignment) | ||||
|     : m_imgui{imgui} | ||||
| { | ||||
|     imgui->begin(_L("Optimize orientation"), ImGuiWindowFlags_NoMove | | ||||
|                                      ImGuiWindowFlags_AlwaysAutoResize | | ||||
|                                      ImGuiWindowFlags_NoCollapse); | ||||
| 
 | ||||
|     // adjust window position to avoid overlap the view toolbar
 | ||||
|     float win_h = ImGui::GetWindowHeight(); | ||||
|     float x = alignment.x, y = alignment.y; | ||||
|     y = std::min(y, alignment.bottom_limit - win_h); | ||||
|     ImGui::SetWindowPos(ImVec2(x, y), ImGuiCond_Always); | ||||
| 
 | ||||
|     ImGui::PushItemWidth(200.f); | ||||
| 
 | ||||
|     size_t methods_cnt = RotoptimizeJob::get_methods_count(); | ||||
|     if (!options_valid) { | ||||
|         for (size_t i = 0; i < methods_cnt; ++i) | ||||
|             options[i] = RotoptimizeJob::get_method_names()[i].c_str(); | ||||
| 
 | ||||
|         options_valid = true; | ||||
|     } | ||||
| 
 | ||||
|     int citem = state.method_id; | ||||
|     if (ImGui::Combo(_L("Choose method").c_str(), &citem, options, methods_cnt) ) { | ||||
|         state.method_id = citem; | ||||
|         wxGetApp().app_config->set("rotoptimize", "method_id", std::to_string(state.method_id)); | ||||
|     } | ||||
| 
 | ||||
|     float accuracy = state.accuracy; | ||||
|     if (imgui->slider_float(_L("Accuracy/Speed"), &accuracy, 0.01f, 1.f, "%.1f")) { | ||||
|         state.accuracy = accuracy; | ||||
|         wxGetApp().app_config->set("rotoptimize", "accuracy", std::to_string(state.accuracy)); | ||||
|     } | ||||
| 
 | ||||
|     ImGui::Separator(); | ||||
| 
 | ||||
|     if ( imgui->button(_L("Optimize")) ) { | ||||
|         wxGetApp().plater()->optimize_rotation(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| GLGizmoRotate3D::RotoptimzeWindow::~RotoptimzeWindow() | ||||
| { | ||||
|     m_imgui->end(); | ||||
| } | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| #define slic3r_GLGizmoRotate_hpp_ | ||||
| 
 | ||||
| #include "GLGizmoBase.hpp" | ||||
| #include "../Jobs/RotoptimizeJob.hpp" | ||||
| 
 | ||||
| 
 | ||||
| namespace Slic3r { | ||||
|  | @ -136,6 +137,39 @@ protected: | |||
|     } | ||||
| 
 | ||||
|     void on_render_input_window(float x, float y, float bottom_limit) override; | ||||
| 
 | ||||
| private: | ||||
| 
 | ||||
|     class RotoptimzeWindow { | ||||
|         ImGuiWrapper *m_imgui = nullptr; | ||||
| 
 | ||||
|         static const char * options []; | ||||
|         static bool options_valid; | ||||
| 
 | ||||
|     public: | ||||
| 
 | ||||
|         struct State { | ||||
|             float  accuracy  = 1.f; | ||||
|             int    method_id = 0; | ||||
|         }; | ||||
| 
 | ||||
|         struct Alignment { float x, y, bottom_limit; }; | ||||
| 
 | ||||
|         RotoptimzeWindow(ImGuiWrapper *   imgui, | ||||
|                          State &          state, | ||||
|                          const Alignment &bottom_limit); | ||||
| 
 | ||||
|         ~RotoptimzeWindow(); | ||||
| 
 | ||||
|         RotoptimzeWindow(const RotoptimzeWindow&) = delete; | ||||
|         RotoptimzeWindow(RotoptimzeWindow &&) = delete; | ||||
|         RotoptimzeWindow& operator=(const RotoptimzeWindow &) = delete; | ||||
|         RotoptimzeWindow& operator=(RotoptimzeWindow &&) = delete; | ||||
|     }; | ||||
| 
 | ||||
|     RotoptimzeWindow::State m_rotoptimizewin_state = {}; | ||||
| 
 | ||||
|     void load_rotoptimize_state(); | ||||
| }; | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
|  |  | |||
|  | @ -8,8 +8,29 @@ | |||
| 
 | ||||
| #include "slic3r/GUI/Plater.hpp" | ||||
| 
 | ||||
| #include "slic3r/GUI/GUI_App.hpp" | ||||
| #include "libslic3r/AppConfig.hpp" | ||||
| 
 | ||||
| namespace Slic3r { namespace GUI { | ||||
| 
 | ||||
| void RotoptimizeJob::prepare() | ||||
| { | ||||
|     std::string accuracy_str = | ||||
|         wxGetApp().app_config->get("rotoptimize", "accuracy"); | ||||
| 
 | ||||
|     std::string method_str = | ||||
|         wxGetApp().app_config->get("rotoptimize", "method_id"); | ||||
| 
 | ||||
|     if (!accuracy_str.empty()) | ||||
|         m_accuracy = std::stof(accuracy_str); | ||||
| 
 | ||||
|     if (!method_str.empty()) | ||||
|         m_method_id = std::stoi(method_str); | ||||
| 
 | ||||
|     m_accuracy = std::max(0.f, std::min(m_accuracy, 1.f)); | ||||
|     m_method_id = std::max(size_t(0), std::min(get_methods_count() - 1, m_method_id)); | ||||
| } | ||||
| 
 | ||||
| void RotoptimizeJob::process() | ||||
| { | ||||
|     int obj_idx = m_plater->get_selected_object_idx(); | ||||
|  | @ -21,7 +42,7 @@ void RotoptimizeJob::process() | |||
| 
 | ||||
|     if (!o || !po) return; | ||||
| 
 | ||||
|     Vec2d r = sla::find_best_rotation(*po, 0.75f, [this](int s) { | ||||
|     Vec2d r = Methods[m_method_id].findfn(*po, m_accuracy, [this](int s) { | ||||
|         if (s > 0 && s < 100) | ||||
|             update_status(s, _(L("Searching for optimal orientation"))); | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,17 +3,58 @@ | |||
| 
 | ||||
| #include "PlaterJob.hpp" | ||||
| 
 | ||||
| namespace Slic3r { namespace GUI { | ||||
| #include "libslic3r/SLA/Rotfinder.hpp" | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| class SLAPrintObject; | ||||
| 
 | ||||
| namespace GUI { | ||||
| 
 | ||||
| class RotoptimizeJob : public PlaterJob | ||||
| { | ||||
|     using FindFn = std::function<Vec2d(const SLAPrintObject &   po, | ||||
|                                        float                    accuracy, | ||||
|                                        sla::RotOptimizeStatusCB statuscb)>; | ||||
| 
 | ||||
|     struct FindMethod { std::string name; FindFn findfn; }; | ||||
| 
 | ||||
|     static inline const FindMethod Methods[] = { | ||||
|         { L("Best misalignment"), sla::find_best_misalignment_rotation }, | ||||
|         { L("Least supports"), sla::find_best_misalignment_rotation } | ||||
|     }; | ||||
| 
 | ||||
|     size_t m_method_id = 0; | ||||
|     float  m_accuracy  = 0.75; | ||||
| protected: | ||||
| 
 | ||||
|     void prepare() override; | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|     RotoptimizeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater) | ||||
|         : PlaterJob{std::move(pri), plater} | ||||
|     {} | ||||
|      | ||||
|     void process() override; | ||||
|     void finalize() override; | ||||
| 
 | ||||
|     static constexpr size_t get_methods_count() { return std::size(Methods); } | ||||
|     static const auto & get_method_names() | ||||
|     { | ||||
|         static bool m_method_names_valid = false; | ||||
|         static std::array<std::string, std::size(Methods)> m_method_names; | ||||
| 
 | ||||
|         if (!m_method_names_valid) { | ||||
| 
 | ||||
|             for (size_t i = 0; i < std::size(Methods); ++i) | ||||
|                 m_method_names[i] = _utf8(Methods[i].name); | ||||
| 
 | ||||
|             m_method_names_valid = true; | ||||
|         } | ||||
| 
 | ||||
|         return m_method_names; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| }} // namespace Slic3r::GUI
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros