mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Add simplification GUI
This commit is contained in:
		
							parent
							
								
									756d2694eb
								
							
						
					
					
						commit
						af526c54f4
					
				
					 12 changed files with 476 additions and 195 deletions
				
			
		|  | @ -57,6 +57,8 @@ set(SLIC3R_GUI_SOURCES | |||
|     GUI/Gizmos/GLGizmoPainterBase.hpp | ||||
|     GUI/Gizmos/GLGizmoSeam.cpp | ||||
|     GUI/Gizmos/GLGizmoSeam.hpp | ||||
|     GUI/Gizmos/GLGizmoSimplify.cpp | ||||
|     GUI/Gizmos/GLGizmoSimplify.hpp | ||||
|     GUI/Gizmos/GLGizmoMmuSegmentation.cpp | ||||
|     GUI/Gizmos/GLGizmoMmuSegmentation.hpp | ||||
|     GUI/GLSelectionRectangle.cpp | ||||
|  | @ -97,8 +99,6 @@ set(SLIC3R_GUI_SOURCES | |||
|     GUI/SavePresetDialog.cpp | ||||
|     GUI/PhysicalPrinterDialog.hpp | ||||
|     GUI/PhysicalPrinterDialog.cpp | ||||
|     GUI/SimplificationDialog.cpp | ||||
|     GUI/SimplificationDialog.hpp | ||||
|     GUI/GUI_Factories.cpp | ||||
|     GUI/GUI_Factories.hpp | ||||
|     GUI/GUI_ObjectList.cpp | ||||
|  |  | |||
|  | @ -4,7 +4,6 @@ | |||
| #include "GUI_Factories.hpp" | ||||
| #include "GUI_ObjectManipulation.hpp" | ||||
| #include "GUI_ObjectLayers.hpp" | ||||
| #include "SimplificationDialog.hpp" | ||||
| #include "GUI_App.hpp" | ||||
| #include "I18N.hpp" | ||||
| #include "Plater.hpp" | ||||
|  | @ -3762,13 +3761,8 @@ void ObjectList::fix_through_netfabb() | |||
| 
 | ||||
| void ObjectList::simplify() | ||||
| { | ||||
|     int obj_idx, vol_idx; | ||||
|     get_selected_item_indexes(obj_idx, vol_idx); | ||||
| 
 | ||||
|     SimplificationDialog dlg(this); | ||||
|     dlg.ShowModal(); | ||||
| 
 | ||||
|     wxGetApp().plater()->simplify(obj_idx, vol_idx); | ||||
|     GLGizmosManager& gizmos_mgr = wxGetApp().plater()->canvas3D()->get_gizmos_manager(); | ||||
|     gizmos_mgr.open_gizmo(GLGizmosManager::EType::Simplify); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::update_item_error_icon(const int obj_idx, const int vol_idx) const  | ||||
|  |  | |||
							
								
								
									
										231
									
								
								src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,231 @@ | |||
| // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
 | ||||
| #include "GLGizmoSimplify.hpp" | ||||
| #include "slic3r/GUI/GLCanvas3D.hpp" | ||||
| #include "slic3r/GUI/GUI_App.hpp" | ||||
| #include "slic3r/GUI/Plater.hpp" | ||||
| #include "slic3r/GUI/GUI_ObjectManipulation.hpp" | ||||
| #include "libslic3r/AppConfig.hpp" | ||||
| #include "libslic3r/Model.hpp" | ||||
| #include "libslic3r/QuadricEdgeCollapse.hpp" | ||||
| 
 | ||||
| namespace Slic3r::GUI { | ||||
| 
 | ||||
| GLGizmoSimplify::GLGizmoSimplify(GLCanvas3D &       parent, | ||||
|                                  const std::string &icon_filename, | ||||
|                                  unsigned int       sprite_id) | ||||
|     : GLGizmoBase(parent, icon_filename, -1) | ||||
|     , state(State::settings) | ||||
|     , is_valid_result(false) | ||||
|     , progress(0) | ||||
|     , volume(nullptr) | ||||
|     , obj_index(0) | ||||
|     , need_reload(false) | ||||
| {} | ||||
| 
 | ||||
| GLGizmoSimplify::~GLGizmoSimplify() {  | ||||
|     state = State::canceling; | ||||
|     if (worker.joinable()) worker.join(); | ||||
| } | ||||
| 
 | ||||
| bool GLGizmoSimplify::on_init() | ||||
| { | ||||
|     //m_grabbers.emplace_back();
 | ||||
|     //m_shortcut_key = WXK_CONTROL_C;
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| std::string GLGizmoSimplify::on_get_name() const | ||||
| { | ||||
|     return (_L("Simplify")).ToUTF8().data(); | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSimplify::on_render() const{} | ||||
| void GLGizmoSimplify::on_render_for_picking() const{} | ||||
| 
 | ||||
| void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limit) | ||||
| { | ||||
|     const Selection &selection = m_parent.get_selection(); | ||||
|     int object_idx = selection.get_object_idx(); | ||||
|     ModelObject *obj = wxGetApp().plater()->model().objects[object_idx]; | ||||
|     ModelVolume *act_volume = obj->volumes.front(); | ||||
| 
 | ||||
| 
 | ||||
|     // Check selection of new volume
 | ||||
|     // Do not reselect object when processing 
 | ||||
|     if (act_volume != volume && state == State::settings) { | ||||
|         obj_index = object_idx; // to remember correct object
 | ||||
|         volume = act_volume; | ||||
|         original_its = {}; | ||||
|         const TriangleMesh &tm = volume->mesh(); | ||||
|         c.wanted_percent = 50.;  // default value
 | ||||
|         c.update_percent(tm.its.indices.size()); | ||||
|         is_valid_result = false; | ||||
|     } | ||||
| 
 | ||||
|     size_t triangle_count = volume->mesh().its.indices.size(); | ||||
|     // already reduced mesh
 | ||||
|     if (original_its.has_value()) | ||||
|         triangle_count = original_its->indices.size(); | ||||
| 
 | ||||
|     int flag = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | | ||||
|                ImGuiWindowFlags_NoCollapse; | ||||
|     m_imgui->begin(_L("Simplify mesh ") + volume->name, flag); | ||||
|     std::string description = "Reduce amout of triangle in mesh( " + | ||||
|                               volume->name + " has " + | ||||
|                               std::to_string(triangle_count) + " triangles)"; | ||||
|     ImGui::Text(description.c_str()); | ||||
|     // First initialization + fix triangle count
 | ||||
|     if (c.wanted_count > triangle_count) c.update_percent(triangle_count); | ||||
|     if (m_imgui->checkbox(_L("Until triangle count is less than "), c.use_count)) { | ||||
|         if (!c.use_count) c.use_error = true; | ||||
|         is_valid_result = false; | ||||
|     } | ||||
| 
 | ||||
|     m_imgui->disabled_begin(!c.use_count); | ||||
|     ImGui::SameLine(); | ||||
|     int wanted_count = c.wanted_count; | ||||
|     if (ImGui::SliderInt("triangles", &wanted_count, 0, | ||||
|                          triangle_count, "%d")) { | ||||
|         c.wanted_count = static_cast<uint32_t>(wanted_count); | ||||
|         c.update_count(triangle_count); | ||||
|         is_valid_result = false; | ||||
|     } | ||||
|     ImGui::SameLine(); | ||||
|     ImGui::SetNextItemWidth(80); | ||||
|     int precision = (c.wanted_percent > 10)? 0: ((c.wanted_percent > 1)? 1:2); | ||||
|     float step = (c.wanted_percent > 10)? 1.f: ((c.wanted_percent > 1)? 0.1f : 0.01f); | ||||
|     if (ImGui::InputFloat("%", &c.wanted_percent, step, 10*step, precision)) { | ||||
|         if (c.wanted_percent < 0.f) c.wanted_percent = 0.f; | ||||
|         if (c.wanted_percent > 100.f) c.wanted_percent = 100.f; | ||||
|         c.update_percent(triangle_count); | ||||
|         is_valid_result = false; | ||||
|     } | ||||
|     m_imgui->disabled_end(); // use_count
 | ||||
| 
 | ||||
|     if (m_imgui->checkbox(_L("Until error"), c.use_error)) { | ||||
|         if (!c.use_error) c.use_count = true; | ||||
|         is_valid_result = false; | ||||
|     } | ||||
|     ImGui::SameLine(); | ||||
|     m_imgui->disabled_begin(!c.use_error); | ||||
|     if (ImGui::InputFloat("(maximal quadric error)", &c.max_error, 0.01f, .1f, 2)) { | ||||
|         if (c.max_error < 0.f) c.max_error = 0.f; | ||||
|         is_valid_result = false; | ||||
|     } | ||||
|     m_imgui->disabled_end(); // use_error
 | ||||
| 
 | ||||
|     if (state == State::settings) { | ||||
|         if (m_imgui->button(_L("Cancel"))) { | ||||
|             if (original_its.has_value()) {  | ||||
|                  set_its(*original_its); | ||||
|                 state = State::close_on_end; | ||||
|             } else { | ||||
|                 close(); | ||||
|             } | ||||
|         } | ||||
|         ImGui::SameLine(); | ||||
|         if (m_imgui->button(_L("Preview"))) { | ||||
|             state = State::simplifying; | ||||
|             // simplify but not aply on mesh
 | ||||
|             process(); | ||||
|         } | ||||
|         ImGui::SameLine(); | ||||
|         if (m_imgui->button(_L("Aply"))) { | ||||
|             if (!is_valid_result) { | ||||
|                 state = State::close_on_end; | ||||
|                 process(); | ||||
|             } else { | ||||
|                 // use preview and close
 | ||||
|                 close(); | ||||
|             } | ||||
|         } | ||||
|     } else {         | ||||
|         m_imgui->disabled_begin(state == State::canceling); | ||||
|         if (m_imgui->button(_L("Cancel"))) state = State::canceling; | ||||
|         m_imgui->disabled_end();  | ||||
| 
 | ||||
|         ImGui::SameLine(); | ||||
|         // draw progress bar
 | ||||
|         ImGui::Text("Processing %c \t %d / 100", | ||||
|                     "|/-\\"[(int) (ImGui::GetTime() / 0.05f) & 3], progress); | ||||
|     } | ||||
|     m_imgui->end(); | ||||
| 
 | ||||
|     if (need_reload) {  | ||||
|         need_reload = false; | ||||
| 
 | ||||
|         // Reload visualization of mesh - change VBO, FBO on GPU
 | ||||
|         m_parent.reload_scene(true); // deactivate gizmo??
 | ||||
|         GLGizmosManager &gizmos_mgr = m_parent.get_gizmos_manager(); | ||||
|         gizmos_mgr.open_gizmo(GLGizmosManager::EType::Simplify); | ||||
| 
 | ||||
|         if (state == State::close_on_end) { | ||||
|             // fix hollowing, sla support points, modifiers, ...
 | ||||
|             auto plater = wxGetApp().plater(); | ||||
|             plater->changed_mesh(obj_index); // deactivate gizmo??
 | ||||
|             // changed_mesh cause close();
 | ||||
|             //close(); 
 | ||||
|         } | ||||
| 
 | ||||
|         // change from simplifying | aply
 | ||||
|         state = State::settings; | ||||
|          | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSimplify::close() { | ||||
|     volume = nullptr; | ||||
|      | ||||
|     // close gizmo == open it again
 | ||||
|     GLGizmosManager &gizmos_mgr = m_parent.get_gizmos_manager(); | ||||
|     gizmos_mgr.open_gizmo(GLGizmosManager::EType::Simplify); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void GLGizmoSimplify::process() | ||||
| { | ||||
|     class SimplifyCanceledException : public std::exception { | ||||
|     public: | ||||
|        const char* what() const throw() { return L("Model simplification has been canceled"); } | ||||
|     }; | ||||
| 
 | ||||
|     if (!original_its.has_value())  | ||||
|         original_its = volume->mesh().its; // copy
 | ||||
|      | ||||
|     auto plater = wxGetApp().plater(); | ||||
|     plater->take_snapshot(_L("Simplify ") + volume->name); | ||||
|     plater->clear_before_change_mesh(obj_index); | ||||
|     progress = 0; | ||||
|     if (worker.joinable()) worker.join(); | ||||
|     worker = std::thread([&]() { | ||||
|         // store original triangles        
 | ||||
|         uint32_t                  triangle_count  = (c.use_count)? c.wanted_count : 0; | ||||
|         float*                    max_error       = (c.use_error)? &c.max_error : nullptr; | ||||
|         std::function<void(void)> throw_on_cancel = [&]() { if ( state == State::canceling) throw SimplifyCanceledException(); };     | ||||
|         std::function<void(int)> statusfn = [&](int percent) { progress = percent; }; | ||||
|         indexed_triangle_set collapsed = original_its.value(); // copy
 | ||||
|         try { | ||||
|             its_quadric_edge_collapse(collapsed, triangle_count, max_error, throw_on_cancel, statusfn); | ||||
|             set_its(collapsed); | ||||
|             is_valid_result = true; | ||||
|         } catch (SimplifyCanceledException &) { | ||||
|             is_valid_result = false; | ||||
|         } | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSimplify::set_its(indexed_triangle_set &its) { | ||||
|     auto tm = std::make_unique<TriangleMesh>(its); | ||||
|     tm->repair(); | ||||
|     volume->set_mesh(std::move(tm)); | ||||
|     volume->set_new_unique_id(); | ||||
|     volume->get_object()->invalidate_bounding_box(); | ||||
|     need_reload = true; | ||||
| } | ||||
| 
 | ||||
| bool GLGizmoSimplify::on_is_activable() const | ||||
| { | ||||
|     return !m_parent.get_selection().is_empty(); | ||||
| } | ||||
| 
 | ||||
| } // namespace Slic3r::GUI
 | ||||
							
								
								
									
										76
									
								
								src/slic3r/GUI/Gizmos/GLGizmoSimplify.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/slic3r/GUI/Gizmos/GLGizmoSimplify.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,76 @@ | |||
| #ifndef slic3r_GLGizmoSimplify_hpp_ | ||||
| #define slic3r_GLGizmoSimplify_hpp_ | ||||
| 
 | ||||
| #include "GLGizmoBase.hpp" | ||||
| #include "libslic3r/Model.hpp" | ||||
| #include <thread> | ||||
| #include <optional> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
| 
 | ||||
| class GLGizmoSimplify : public GLGizmoBase | ||||
| { | ||||
|     enum class State { | ||||
|         settings, | ||||
|         simplifying, // start processing
 | ||||
|         canceling, // canceled
 | ||||
|         successfull, // successful simplified
 | ||||
|         close_on_end | ||||
|     } state; | ||||
| 
 | ||||
|     bool is_valid_result; // differ what to do in apply
 | ||||
| 
 | ||||
|     int progress; | ||||
|      | ||||
|     ModelVolume *volume; | ||||
|     size_t obj_index; | ||||
|     std::optional<indexed_triangle_set> original_its; | ||||
| 
 | ||||
|     bool need_reload; // after simplify, glReload must be on main thread
 | ||||
|     std::thread worker; | ||||
| public: | ||||
|     GLGizmoSimplify(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); | ||||
|     virtual ~GLGizmoSimplify(); | ||||
|     void set_selectable(bool value); | ||||
| protected: | ||||
|     virtual bool on_init() override; | ||||
|     virtual std::string on_get_name() const override; | ||||
|     virtual void on_render() const override; | ||||
|     virtual void on_render_for_picking() const override;     | ||||
|     virtual void on_render_input_window(float x, float y, float bottom_limit) override; | ||||
|     virtual bool on_is_activable() const override; | ||||
|     virtual bool on_is_selectable() const override { return false; }; | ||||
| 
 | ||||
| private: | ||||
|     void close(); | ||||
|     void process(); | ||||
|     void set_its(indexed_triangle_set &its); | ||||
|     struct Configuration | ||||
|     { | ||||
|         bool use_count = true; | ||||
|         // minimal triangle count
 | ||||
|         float    wanted_percent = 50.f; | ||||
|         uint32_t wanted_count   = 0; // initialize by percents
 | ||||
| 
 | ||||
|         bool use_error = false; | ||||
|         // maximal quadric error
 | ||||
|         float max_error = 1.; | ||||
| 
 | ||||
|         void update_count(size_t triangle_count) | ||||
|         { | ||||
|             wanted_percent = (float) wanted_count / triangle_count * 100.f; | ||||
|         } | ||||
|         void update_percent(size_t triangle_count) | ||||
|         { | ||||
|             wanted_count = static_cast<uint32_t>( | ||||
|                 std::round(triangle_count * wanted_percent / 100.f)); | ||||
|         } | ||||
|     }; | ||||
|     Configuration c; | ||||
| }; | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
| #endif // slic3r_GLGizmoSimplify_hpp_
 | ||||
|  | @ -20,6 +20,7 @@ | |||
| #include "slic3r/GUI/Gizmos/GLGizmoHollow.hpp" | ||||
| #include "slic3r/GUI/Gizmos/GLGizmoSeam.hpp" | ||||
| #include "slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp" | ||||
| #include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp" | ||||
| 
 | ||||
| #include "libslic3r/Model.hpp" | ||||
| #include "libslic3r/PresetBundle.hpp" | ||||
|  | @ -110,6 +111,7 @@ bool GLGizmosManager::init() | |||
|     m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, "fdm_supports.svg", 7)); | ||||
|     m_gizmos.emplace_back(new GLGizmoSeam(m_parent, "seam.svg", 8)); | ||||
|     m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, "fdm_supports.svg", 9)); | ||||
|     m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "cut.svg", 10)); | ||||
| 
 | ||||
|     m_common_gizmos_data.reset(new CommonGizmosDataPool(&m_parent)); | ||||
| 
 | ||||
|  | @ -169,7 +171,7 @@ void GLGizmosManager::reset_all_states() | |||
| bool GLGizmosManager::open_gizmo(EType type) | ||||
| { | ||||
|     int idx = int(type); | ||||
|     if (m_gizmos[idx]->is_selectable() && m_gizmos[idx]->is_activable()) { | ||||
|     if (/*m_gizmos[idx]->is_selectable() &&*/ m_gizmos[idx]->is_activable()) { | ||||
|         activate_gizmo(m_current == idx ? Undefined : (EType)idx); | ||||
|         update_data(); | ||||
|         return true; | ||||
|  | @ -1021,6 +1023,8 @@ void GLGizmosManager::do_render_overlay() const | |||
|     float u_offset = 1.0f / (float)tex_width; | ||||
|     float v_offset = 1.0f / (float)tex_height; | ||||
| 
 | ||||
|     float toolbar_top = 0.f; | ||||
|     float current_y   = 0.f; | ||||
|     for (size_t idx : selectable_idxs) | ||||
|     { | ||||
|         GLGizmoBase* gizmo = m_gizmos[idx].get(); | ||||
|  | @ -1035,11 +1039,14 @@ void GLGizmosManager::do_render_overlay() const | |||
| 
 | ||||
|         GLTexture::render_sub_texture(icons_texture_id, zoomed_top_x, zoomed_top_x + zoomed_icons_size, zoomed_top_y - zoomed_icons_size, zoomed_top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); | ||||
|         if (idx == m_current) { | ||||
|             float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height(); | ||||
|             gizmo->render_input_window(width, 0.5f * cnv_h - zoomed_top_y * zoom, toolbar_top); | ||||
|             toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height(); | ||||
|             current_y = 0.5f * cnv_h - zoomed_top_y * zoom; | ||||
|         } | ||||
|         zoomed_top_y -= zoomed_stride_y; | ||||
|     } | ||||
| 
 | ||||
|     if (m_current != Undefined)  | ||||
|         m_gizmos[m_current]->render_input_window(width, current_y, toolbar_top); | ||||
| } | ||||
| 
 | ||||
| float GLGizmosManager::get_scaled_total_height() const | ||||
|  |  | |||
|  | @ -69,6 +69,7 @@ public: | |||
|         FdmSupports, | ||||
|         Seam, | ||||
|         MmuSegmentation, | ||||
|         Simplify, | ||||
|         Undefined | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1730,7 +1730,6 @@ struct Plater::priv | |||
|     void replace_with_stl(); | ||||
|     void reload_all_from_disk(); | ||||
|     void fix_through_netfabb(const int obj_idx, const int vol_idx = -1); | ||||
|     void simplify(const int obj_idx, const int vol_idx = -1); | ||||
| 
 | ||||
|     void set_current_panel(wxPanel* panel); | ||||
| 
 | ||||
|  | @ -3555,70 +3554,10 @@ void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* = | |||
|     // size_t snapshot_time = undo_redo_stack().active_snapshot_time();
 | ||||
|     Plater::TakeSnapshot snapshot(q, _L("Fix through NetFabb")); | ||||
| 
 | ||||
|     q->clear_before_change_mesh(obj_idx); | ||||
|     ModelObject* mo = model.objects[obj_idx]; | ||||
| 
 | ||||
|     // If there are custom supports/seams/mmu segmentation, remove them. Fixed mesh
 | ||||
|     // may be different and they would make no sense.
 | ||||
|     bool paint_removed = false; | ||||
|     for (ModelVolume* mv : mo->volumes) { | ||||
|         paint_removed |= ! mv->supported_facets.empty() || ! mv->seam_facets.empty() || ! mv->mmu_segmentation_facets.empty(); | ||||
|         mv->supported_facets.clear(); | ||||
|         mv->seam_facets.clear(); | ||||
|         mv->mmu_segmentation_facets.clear(); | ||||
|     } | ||||
|     if (paint_removed) { | ||||
|         // snapshot_time is captured by copy so the lambda knows where to undo/redo to.
 | ||||
|         notification_manager->push_notification( | ||||
|                     NotificationType::CustomSupportsAndSeamRemovedAfterRepair, | ||||
|                     NotificationManager::NotificationLevel::RegularNotification, | ||||
|                     _u8L("Custom supports and seams were removed after repairing the mesh.")); | ||||
| //                    _u8L("Undo the repair"),
 | ||||
| //                    [this, snapshot_time](wxEvtHandler*){
 | ||||
| //                        // Make sure the snapshot is still available and that
 | ||||
| //                        // we are in the main stack and not in a gizmo-stack.
 | ||||
| //                        if (undo_redo_stack().has_undo_snapshot(snapshot_time)
 | ||||
| //                         && q->canvas3D()->get_gizmos_manager().get_current() == nullptr)
 | ||||
| //                            undo_redo_to(snapshot_time);
 | ||||
| //                        else
 | ||||
| //                            notification_manager->push_notification(
 | ||||
| //                                NotificationType::CustomSupportsAndSeamRemovedAfterRepair,
 | ||||
| //                                NotificationManager::NotificationLevel::RegularNotification,
 | ||||
| //                                _u8L("Cannot undo to before the mesh repair!"));
 | ||||
| //                        return true;
 | ||||
| //                    });
 | ||||
|     } | ||||
| 
 | ||||
|     fix_model_by_win10_sdk_gui(*mo, vol_idx); | ||||
|     sla::reproject_points_and_holes(mo); | ||||
|     this->update(); | ||||
|     this->object_list_changed(); | ||||
|     this->schedule_background_process(); | ||||
| } | ||||
| 
 | ||||
| void Plater::priv::simplify(const int obj_idx, const int vol_idx/* = -1*/) | ||||
| { | ||||
|     if (obj_idx < 0) | ||||
|         return; | ||||
| 
 | ||||
|     // Do not fix anything when a gizmo is open. There might be issues with updates
 | ||||
|     // and what is worse, the snapshot time would refer to the internal stack.
 | ||||
|     if (q->canvas3D()->get_gizmos_manager().get_current_type() != GLGizmosManager::Undefined) { | ||||
|         notification_manager->push_notification( | ||||
|                     NotificationType::CustomSupportsAndSeamRemovedAfterRepair, | ||||
|                     NotificationManager::NotificationLevel::RegularNotification, | ||||
|                     _u8L("ERROR: Please close all manipulators available from " | ||||
|                          "the left toolbar before fixing the mesh.")); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // size_t snapshot_time = undo_redo_stack().active_snapshot_time();
 | ||||
|     Plater::TakeSnapshot snapshot(q, _L("Symplify model")); | ||||
| 
 | ||||
|     // ToDo
 | ||||
| 
 | ||||
|     this->update(); | ||||
|     this->object_list_changed(); | ||||
|     this->schedule_background_process(); | ||||
|     q->changed_mesh(obj_idx); | ||||
| } | ||||
| 
 | ||||
| void Plater::priv::set_current_panel(wxPanel* panel) | ||||
|  | @ -6262,6 +6201,51 @@ bool Plater::set_printer_technology(PrinterTechnology printer_technology) | |||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void Plater::clear_before_change_mesh(int obj_idx) | ||||
| { | ||||
|     ModelObject* mo = model().objects[obj_idx]; | ||||
| 
 | ||||
|     // If there are custom supports/seams/mmu segmentation, remove them. Fixed mesh
 | ||||
|     // may be different and they would make no sense.
 | ||||
|     bool paint_removed = false; | ||||
|     for (ModelVolume* mv : mo->volumes) { | ||||
|         paint_removed |= ! mv->supported_facets.empty() || ! mv->seam_facets.empty() || ! mv->mmu_segmentation_facets.empty(); | ||||
|         mv->supported_facets.clear(); | ||||
|         mv->seam_facets.clear(); | ||||
|         mv->mmu_segmentation_facets.clear(); | ||||
|     } | ||||
|     if (paint_removed) { | ||||
|         // snapshot_time is captured by copy so the lambda knows where to undo/redo to.
 | ||||
|         get_notification_manager()->push_notification( | ||||
|                     NotificationType::CustomSupportsAndSeamRemovedAfterRepair, | ||||
|                     NotificationManager::NotificationLevel::RegularNotification, | ||||
|                     _u8L("Custom supports and seams were removed after repairing the mesh.")); | ||||
| //                    _u8L("Undo the repair"),
 | ||||
| //                    [this, snapshot_time](wxEvtHandler*){
 | ||||
| //                        // Make sure the snapshot is still available and that
 | ||||
| //                        // we are in the main stack and not in a gizmo-stack.
 | ||||
| //                        if (undo_redo_stack().has_undo_snapshot(snapshot_time)
 | ||||
| //                         && q->canvas3D()->get_gizmos_manager().get_current() == nullptr)
 | ||||
| //                            undo_redo_to(snapshot_time);
 | ||||
| //                        else
 | ||||
| //                            notification_manager->push_notification(
 | ||||
| //                                NotificationType::CustomSupportsAndSeamRemovedAfterRepair,
 | ||||
| //                                NotificationManager::NotificationLevel::RegularNotification,
 | ||||
| //                                _u8L("Cannot undo to before the mesh repair!"));
 | ||||
| //                        return true;
 | ||||
| //                    });
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Plater::changed_mesh(int obj_idx) | ||||
| { | ||||
|     ModelObject* mo = model().objects[obj_idx]; | ||||
|     sla::reproject_points_and_holes(mo); | ||||
|     update(); | ||||
|     p->object_list_changed(); | ||||
|     p->schedule_background_process(); | ||||
| } | ||||
| 
 | ||||
| void Plater::changed_object(int obj_idx) | ||||
| { | ||||
|     if (obj_idx < 0) | ||||
|  | @ -6343,7 +6327,6 @@ void Plater::suppress_background_process(const bool stop_background_process) | |||
| } | ||||
| 
 | ||||
| void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); } | ||||
| void Plater::simplify(const int obj_idx, const int vol_idx/* = -1*/) { p->simplify(obj_idx, vol_idx); } | ||||
| void Plater::mirror(Axis axis)      { p->mirror(axis); } | ||||
| void Plater::split_object()         { p->split_object(); } | ||||
| void Plater::split_volume()         { p->split_volume(); } | ||||
|  |  | |||
|  | @ -230,13 +230,16 @@ public: | |||
|     void reslice_SLA_supports(const ModelObject &object, bool postpone_error_messages = false); | ||||
|     void reslice_SLA_hollowing(const ModelObject &object, bool postpone_error_messages = false); | ||||
|     void reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &object, bool postpone_error_messages = false); | ||||
| 
 | ||||
|     void clear_before_change_mesh(int obj_idx); | ||||
|     void changed_mesh(int obj_idx); | ||||
| 
 | ||||
|     void changed_object(int obj_idx); | ||||
|     void changed_objects(const std::vector<size_t>& object_idxs); | ||||
|     void schedule_background_process(bool schedule = true); | ||||
|     bool is_background_process_update_scheduled() const; | ||||
|     void suppress_background_process(const bool stop_background_process) ; | ||||
|     void fix_through_netfabb(const int obj_idx, const int vol_idx = -1); | ||||
|     void simplify(const int obj_idx, const int vol_idx = -1); | ||||
|     void send_gcode(); | ||||
| 	void eject_drive(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,91 +0,0 @@ | |||
| #include "SimplificationDialog.hpp" | ||||
| 
 | ||||
| #include <cstddef> | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <boost/algorithm/string.hpp> | ||||
| 
 | ||||
| #include <wx/sizer.h> | ||||
| #include <wx/stattext.h> | ||||
| #include <wx/textctrl.h> | ||||
| #include <wx/button.h> | ||||
| #include <wx/statbox.h> | ||||
| #include <wx/wupdlock.h> | ||||
| 
 | ||||
| #include "GUI.hpp" | ||||
| #include "GUI_App.hpp" | ||||
| #include "format.hpp" | ||||
| #include "wxExtensions.hpp" | ||||
| #include "I18N.hpp" | ||||
| #include "libslic3r/Utils.hpp" | ||||
| 
 | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
| 
 | ||||
| #define BORDER_W 10 | ||||
| 
 | ||||
| SimplificationDialog::SimplificationDialog(wxWindow* parent) : | ||||
|     DPIDialog(parent, wxID_ANY, _L("Name of Dialog"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), -1), wxDEFAULT_DIALOG_STYLE/* | wxRESIZE_BORDER*/) | ||||
| { | ||||
|     SetFont(wxGetApp().normal_font()); | ||||
| 
 | ||||
|     wxStaticText* label_top = new wxStaticText(this, wxID_ANY, _L("Some text") + ":"); | ||||
| 
 | ||||
|     wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(3, 2, 1, 2); | ||||
|     grid_sizer->AddGrowableCol(1, 1); | ||||
|     grid_sizer->SetFlexibleDirection(wxBOTH); | ||||
| 
 | ||||
|     for (int i = 0; i < 3; i++) { | ||||
|         auto* text = new wxStaticText(this, wxID_ANY, _L("Text") + " " + std::to_string(i) + " :"); | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
|         long style = wxBORDER_SIMPLE; | ||||
| #else | ||||
|         long style = 0 | ||||
| #endif | ||||
|         auto value = new wxTextCtrl(this, wxID_ANY, "Some Value", wxDefaultPosition, wxDefaultSize, style); | ||||
| 
 | ||||
|         grid_sizer->Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 4); | ||||
|         grid_sizer->Add(value, 1, wxEXPAND | wxBOTTOM, 1); | ||||
|     } | ||||
| 
 | ||||
|     wxStdDialogButtonSizer* btns = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL); | ||||
|     this->Bind(wxEVT_BUTTON, &SimplificationDialog::OnOK, this, wxID_OK); | ||||
| 
 | ||||
|     wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); | ||||
| 
 | ||||
|     topSizer->Add(label_top , 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, BORDER_W); | ||||
|     topSizer->Add(grid_sizer, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, BORDER_W); | ||||
|     topSizer->Add(btns      , 0, wxEXPAND | wxALL, BORDER_W);  | ||||
| 
 | ||||
|     SetSizer(topSizer); | ||||
|     topSizer->SetSizeHints(this); | ||||
| 
 | ||||
|     wxGetApp().UpdateDlgDarkUI(this); | ||||
| 
 | ||||
|     this->CenterOnScreen(); | ||||
| } | ||||
| 
 | ||||
| SimplificationDialog::~SimplificationDialog() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void SimplificationDialog::on_dpi_changed(const wxRect& suggested_rect) | ||||
| { | ||||
|     const int& em = em_unit(); | ||||
|     msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL }); | ||||
| 
 | ||||
|     const wxSize& size = wxSize(45 * em, 35 * em); | ||||
|     SetMinSize(size); | ||||
| 
 | ||||
|     Fit(); | ||||
|     Refresh(); | ||||
| } | ||||
| 
 | ||||
| void SimplificationDialog::OnOK(wxEvent& event) | ||||
| { | ||||
|     event.Skip(); | ||||
| } | ||||
| 
 | ||||
| }}    // namespace Slic3r::GUI
 | ||||
|  | @ -1,25 +0,0 @@ | |||
| #ifndef slic3r_SimplificationDialog_hpp_ | ||||
| #define slic3r_SimplificationDialog_hpp_ | ||||
| 
 | ||||
| #include "GUI_Utils.hpp" | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
| 
 | ||||
| class SimplificationDialog : public DPIDialog | ||||
| { | ||||
|     void OnOK(wxEvent& event); | ||||
| 
 | ||||
| public: | ||||
|     SimplificationDialog(wxWindow* parent); | ||||
|     ~SimplificationDialog(); | ||||
| 
 | ||||
| protected: | ||||
|     void on_dpi_changed(const wxRect& suggested_rect) override; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
| #endif //slic3r_SimplificationDialog_hpp_
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Filip Sykala
						Filip Sykala