mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Added 'keep min' option to smoothing algorithm
This commit is contained in:
		
							parent
							
								
									955439b3ba
								
							
						
					
					
						commit
						aea32ffe72
					
				
					 5 changed files with 48 additions and 28 deletions
				
			
		|  | @ -346,9 +346,9 @@ std::vector<coordf_t> layer_height_profile_adaptive( | |||
|     return layer_height_profile; | ||||
| } | ||||
| 
 | ||||
| std::vector<double> smooth_height_profile(const std::vector<double>& profile, const SlicingParameters& slicing_params, unsigned int radius) | ||||
| std::vector<double> smooth_height_profile(const std::vector<double>& profile, const SlicingParameters& slicing_params, const HeightProfileSmoothingParams& smoothing_params) | ||||
| { | ||||
|     auto gauss_blur = [&slicing_params](const std::vector<double>& profile, unsigned int radius) -> std::vector<double> { | ||||
|     auto gauss_blur = [&slicing_params](const std::vector<double>& profile, const HeightProfileSmoothingParams& smoothing_params) -> std::vector<double> { | ||||
|         auto gauss_kernel = [] (unsigned int radius) -> std::vector<double> { | ||||
|             unsigned int size = 2 * radius + 1; | ||||
|             std::vector<double> ret; | ||||
|  | @ -374,7 +374,8 @@ std::vector<double> smooth_height_profile(const std::vector<double>& profile, co | |||
|         // not enough data to smmoth
 | ||||
|         if ((int)profile.size() - (int)skip_count < 6) | ||||
|             return profile; | ||||
| 
 | ||||
|          | ||||
|         unsigned int radius = std::max(smoothing_params.radius, (unsigned int)1); | ||||
|         std::vector<double> kernel = gauss_kernel(radius); | ||||
|         int two_radius = 2 * (int)radius; | ||||
| 
 | ||||
|  | @ -388,15 +389,16 @@ std::vector<double> smooth_height_profile(const std::vector<double>& profile, co | |||
|             ret.push_back(profile[i]); | ||||
|         } | ||||
| 
 | ||||
|         // smooth the rest of the profile
 | ||||
|         double med_h = 0.5 * (slicing_params.min_layer_height + slicing_params.max_layer_height); | ||||
|         double half_delta_h = 0.5 * (slicing_params.max_layer_height - slicing_params.min_layer_height); | ||||
|         double inv_half_delta_h = (half_delta_h > 0.0) ? 1.0 / half_delta_h : 1.0; | ||||
|         // smooth the rest of the profile by biasing a gaussian blur
 | ||||
|         // the bias moves the smoothed profile closer to the min_layer_height
 | ||||
|         double delta_h = slicing_params.max_layer_height - slicing_params.min_layer_height; | ||||
|         double inv_delta_h = (delta_h != 0.0) ? 1.0 / delta_h : 1.0; | ||||
| 
 | ||||
|         double max_dz_band = (double)radius * slicing_params.layer_height; | ||||
|         for (size_t i = skip_count; i < size; i += 2) | ||||
|         { | ||||
|             double zi = profile[i]; | ||||
|             double hi = profile[i + 1]; | ||||
|             ret.push_back(zi); | ||||
|             ret.push_back(0.0); | ||||
|             double& height = ret.back(); | ||||
|  | @ -409,20 +411,22 @@ std::vector<double> smooth_height_profile(const std::vector<double>& profile, co | |||
|                 double dz = std::abs(zi - profile[j]); | ||||
|                 if (dz * slicing_params.layer_height <= max_dz_band) | ||||
|                 { | ||||
|                     double dh = std::abs(profile[j + 1] - med_h); | ||||
|                     double weight = kernel[kernel_id] * dh * inv_half_delta_h; | ||||
|                     double dh = std::abs(slicing_params.max_layer_height - profile[j + 1]); | ||||
|                     double weight = kernel[kernel_id] * sqrt(dh * inv_delta_h); | ||||
|                     height += weight * profile[j + 1]; | ||||
|                     weight_total += weight; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             height = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, (weight_total != 0.0) ? height /= weight_total : profile[i + 1]); | ||||
|             height = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, (weight_total != 0.0) ? height /= weight_total : hi); | ||||
|             if (smoothing_params.keep_min) | ||||
|                 height = std::min(height, hi); | ||||
|         } | ||||
| 
 | ||||
|         return ret; | ||||
|     }; | ||||
| 
 | ||||
|     return gauss_blur(profile, std::max(radius, (unsigned int)1)); | ||||
|     return gauss_blur(profile, smoothing_params); | ||||
| } | ||||
| 
 | ||||
| void adjust_layer_height_profile( | ||||
|  |  | |||
|  | @ -147,10 +147,18 @@ extern std::vector<double> layer_height_profile_adaptive( | |||
|     const SlicingParameters& slicing_params, | ||||
|     const ModelObject& object, float cusp_value); | ||||
| 
 | ||||
| struct HeightProfileSmoothingParams | ||||
| { | ||||
|     unsigned int radius; | ||||
|     bool keep_min; | ||||
| 
 | ||||
|     HeightProfileSmoothingParams() : radius(5), keep_min(false) {} | ||||
|     HeightProfileSmoothingParams(unsigned int radius, bool keep_min) : radius(radius), keep_min(keep_min) {} | ||||
| }; | ||||
| 
 | ||||
| extern std::vector<double> smooth_height_profile( | ||||
|     const std::vector<double>& profile,  | ||||
|     const SlicingParameters& slicing_params, | ||||
|     unsigned int radius); | ||||
|     const std::vector<double>& profile, const SlicingParameters& slicing_params, | ||||
|     const HeightProfileSmoothingParams& smoothing_params); | ||||
| #else | ||||
| extern std::vector<coordf_t> layer_height_profile_adaptive( | ||||
|     const SlicingParameters     &slicing_params, | ||||
|  |  | |||
|  | @ -132,7 +132,6 @@ GLCanvas3D::LayersEditing::LayersEditing() | |||
|     , m_layer_height_profile_modified(false) | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     , m_adaptive_cusp(0.2f) | ||||
|     , m_smooth_radius(5) | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|     , state(Unknown) | ||||
|     , band_width(2.0f) | ||||
|  | @ -283,7 +282,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const | |||
| 
 | ||||
|     ImGui::Separator(); | ||||
|     if (imgui.button(_(L("Smooth")))) | ||||
|         wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event<unsigned int>(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, m_smooth_radius)); | ||||
|         wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), HeightProfileSmoothEvent(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, m_smooth_params )); | ||||
| 
 | ||||
|     ImGui::SameLine(); | ||||
|     ImGui::SetCursorPosX(text_align); | ||||
|  | @ -291,9 +290,16 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const | |||
|     ImGui::SameLine(); | ||||
|     ImGui::PushItemWidth(120.0f); | ||||
|     ImGui::SetCursorPosX(widget_align); | ||||
|     int radius = (int)m_smooth_radius; | ||||
|     int radius = (int)m_smooth_params.radius; | ||||
|     if (ImGui::SliderInt("##1", &radius, 1, 10)) | ||||
|         m_smooth_radius = (unsigned int)radius; | ||||
|         m_smooth_params.radius = (unsigned int)radius; | ||||
| 
 | ||||
|     ImGui::SetCursorPosX(text_align); | ||||
|     imgui.text(_(L("Keep min"))); | ||||
|     ImGui::SameLine(); | ||||
|     ImGui::PushItemWidth(120.0f); | ||||
|     ImGui::SetCursorPosX(widget_align); | ||||
|     imgui.checkbox("##2", m_smooth_params.keep_min); | ||||
| 
 | ||||
|     ImGui::Separator(); | ||||
|     if (imgui.button(_(L("Reset")))) | ||||
|  | @ -609,9 +615,9 @@ void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas | |||
|     canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, unsigned int radius) | ||||
| void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_params) | ||||
| { | ||||
|     m_layer_height_profile = smooth_height_profile(m_layer_height_profile, *m_slicing_parameters, radius); | ||||
|     m_layer_height_profile = smooth_height_profile(m_layer_height_profile, *m_slicing_parameters, smoothing_params); | ||||
|     const_cast<ModelObject*>(m_model_object)->layer_height_profile = m_layer_height_profile; | ||||
|     m_layers_texture.valid = false; | ||||
|     canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); | ||||
|  | @ -1245,7 +1251,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); | |||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, Event<unsigned int>); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| #if ENABLE_THUMBNAIL_GENERATOR | ||||
|  | @ -1564,9 +1570,9 @@ void GLCanvas3D::adaptive_layer_height_profile(float cusp) | |||
|     m_dirty = true; | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::smooth_layer_height_profile(unsigned int radius) | ||||
| void GLCanvas3D::smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params) | ||||
| { | ||||
|     m_layers_editing.smooth_layer_height_profile(*this, radius); | ||||
|     m_layers_editing.smooth_layer_height_profile(*this, smoothing_params); | ||||
|     m_layers_editing.state = LayersEditing::Completed; | ||||
|     m_dirty = true; | ||||
| } | ||||
|  |  | |||
|  | @ -81,6 +81,8 @@ template <size_t N> using Vec2dsEvent = ArrayEvent<Vec2d, N>; | |||
| using Vec3dEvent = Event<Vec3d>; | ||||
| template <size_t N> using Vec3dsEvent = ArrayEvent<Vec3d, N>; | ||||
| 
 | ||||
| using HeightProfileSmoothEvent = Event<HeightProfileSmoothingParams>; | ||||
| 
 | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent); | ||||
|  | @ -107,7 +109,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); | |||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, Event<unsigned int>); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| class GLCanvas3D | ||||
|  | @ -182,7 +184,7 @@ private: | |||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         mutable float               m_adaptive_cusp; | ||||
|         mutable unsigned int        m_smooth_radius; | ||||
|         mutable HeightProfileSmoothingParams m_smooth_params; | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|         class LayersTexture | ||||
|  | @ -233,7 +235,7 @@ private: | |||
|         void reset_layer_height_profile(GLCanvas3D& canvas); | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         void adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp); | ||||
|             void smooth_layer_height_profile(GLCanvas3D& canvas, unsigned int radius); | ||||
|         void smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_paramsn); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|         static float get_cursor_z_relative(const GLCanvas3D& canvas); | ||||
|  | @ -531,7 +533,7 @@ public: | |||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     void reset_layer_height_profile(); | ||||
|     void adaptive_layer_height_profile(float cusp); | ||||
|     void smooth_layer_height_profile(unsigned int radius); | ||||
|     void smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|     bool is_reload_delayed() const; | ||||
|  |  | |||
|  | @ -2090,7 +2090,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event<float>& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](Event<unsigned int>& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](HeightProfileSmoothEvent& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); }); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|     // 3DScene/Toolbar:
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri