mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -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
 | } // namespace
 | ||||||
| 
 | 
 | ||||||
| Vec2d find_best_rotation(const SLAPrintObject &   po, | Vec2d find_best_misalignment_rotation(const SLAPrintObject &   po, | ||||||
|                                       float                    accuracy, |                                       float                    accuracy, | ||||||
|                                       std::function<bool(int)> statuscb) |                                       std::function<bool(int)> statuscb) | ||||||
| { | { | ||||||
|  | @ -156,12 +156,4 @@ Vec2d find_best_rotation(const SLAPrintObject &   po, | ||||||
|     return {rot[0], rot[1]}; |     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
 | }} // namespace Slic3r::sla
 | ||||||
|  |  | ||||||
|  | @ -9,9 +9,12 @@ | ||||||
| namespace Slic3r { | namespace Slic3r { | ||||||
| 
 | 
 | ||||||
| class SLAPrintObject; | class SLAPrintObject; | ||||||
|  | class TriangleMesh; | ||||||
| 
 | 
 | ||||||
| namespace sla { | namespace sla { | ||||||
| 
 | 
 | ||||||
|  | using RotOptimizeStatusCB = std::function<bool(int)>; | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|   * The function should find the best rotation for SLA upside down printing. |   * 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) |   * @return Returns the rotations around each axis (x, y, z) | ||||||
|   */ |   */ | ||||||
| Vec2d find_best_rotation( | Vec2d find_best_misalignment_rotation( | ||||||
|         const SLAPrintObject& modelobj, |         const SLAPrintObject& modelobj, | ||||||
|         float accuracy = 1.0f, |         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 sla
 | ||||||
| } // namespace Slic3r
 | } // namespace Slic3r
 | ||||||
|  |  | ||||||
|  | @ -7,9 +7,10 @@ | ||||||
| 
 | 
 | ||||||
| #include "slic3r/GUI/GUI_App.hpp" | #include "slic3r/GUI/GUI_App.hpp" | ||||||
| #include "slic3r/GUI/GUI.hpp" | #include "slic3r/GUI/GUI.hpp" | ||||||
|  | #include "slic3r/GUI/Plater.hpp" | ||||||
| #include "libslic3r/PresetBundle.hpp" | #include "libslic3r/PresetBundle.hpp" | ||||||
| 
 | 
 | ||||||
| #include "libslic3r/SLA/Rotfinder.hpp" | #include "slic3r/GUI/Jobs/RotoptimizeJob.hpp" | ||||||
| 
 | 
 | ||||||
| namespace Slic3r { | namespace Slic3r { | ||||||
| namespace GUI { | 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) |     if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) | ||||||
|         return; |         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 | 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); |         m_gizmos[i].set_group_id(i); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     std::cout << "Load rotopt state" << std::endl; | ||||||
|  |     load_rotoptimize_state(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool GLGizmoRotate3D::on_init() | bool GLGizmoRotate3D::on_init() | ||||||
|  | @ -492,5 +513,57 @@ void GLGizmoRotate3D::on_render() const | ||||||
|         m_gizmos[Z].render(); |         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 GUI
 | ||||||
| } // namespace Slic3r
 | } // namespace Slic3r
 | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| #define slic3r_GLGizmoRotate_hpp_ | #define slic3r_GLGizmoRotate_hpp_ | ||||||
| 
 | 
 | ||||||
| #include "GLGizmoBase.hpp" | #include "GLGizmoBase.hpp" | ||||||
|  | #include "../Jobs/RotoptimizeJob.hpp" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| namespace Slic3r { | namespace Slic3r { | ||||||
|  | @ -136,6 +137,39 @@ protected: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void on_render_input_window(float x, float y, float bottom_limit) override; |     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
 | } // namespace GUI
 | ||||||
|  |  | ||||||
|  | @ -8,8 +8,29 @@ | ||||||
| 
 | 
 | ||||||
| #include "slic3r/GUI/Plater.hpp" | #include "slic3r/GUI/Plater.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include "slic3r/GUI/GUI_App.hpp" | ||||||
|  | #include "libslic3r/AppConfig.hpp" | ||||||
|  | 
 | ||||||
| namespace Slic3r { namespace GUI { | 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() | void RotoptimizeJob::process() | ||||||
| { | { | ||||||
|     int obj_idx = m_plater->get_selected_object_idx(); |     int obj_idx = m_plater->get_selected_object_idx(); | ||||||
|  | @ -21,7 +42,7 @@ void RotoptimizeJob::process() | ||||||
| 
 | 
 | ||||||
|     if (!o || !po) return; |     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) |         if (s > 0 && s < 100) | ||||||
|             update_status(s, _(L("Searching for optimal orientation"))); |             update_status(s, _(L("Searching for optimal orientation"))); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,17 +3,58 @@ | ||||||
| 
 | 
 | ||||||
| #include "PlaterJob.hpp" | #include "PlaterJob.hpp" | ||||||
| 
 | 
 | ||||||
| namespace Slic3r { namespace GUI { | #include "libslic3r/SLA/Rotfinder.hpp" | ||||||
|  | 
 | ||||||
|  | namespace Slic3r { | ||||||
|  | 
 | ||||||
|  | class SLAPrintObject; | ||||||
|  | 
 | ||||||
|  | namespace GUI { | ||||||
| 
 | 
 | ||||||
| class RotoptimizeJob : public PlaterJob | 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: | public: | ||||||
|  | 
 | ||||||
|     RotoptimizeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater) |     RotoptimizeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater) | ||||||
|         : PlaterJob{std::move(pri), plater} |         : PlaterJob{std::move(pri), plater} | ||||||
|     {} |     {} | ||||||
|      |      | ||||||
|     void process() override; |     void process() override; | ||||||
|     void finalize() 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
 | }} // namespace Slic3r::GUI
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros