mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-25 15:47:25 +08:00
ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Added 'keep min' option to smoothing algorithm
This commit is contained in:
parent
955439b3ba
commit
aea32ffe72
@ -346,9 +346,9 @@ std::vector<coordf_t> layer_height_profile_adaptive(
|
|||||||
return layer_height_profile;
|
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> {
|
auto gauss_kernel = [] (unsigned int radius) -> std::vector<double> {
|
||||||
unsigned int size = 2 * radius + 1;
|
unsigned int size = 2 * radius + 1;
|
||||||
std::vector<double> ret;
|
std::vector<double> ret;
|
||||||
@ -375,6 +375,7 @@ std::vector<double> smooth_height_profile(const std::vector<double>& profile, co
|
|||||||
if ((int)profile.size() - (int)skip_count < 6)
|
if ((int)profile.size() - (int)skip_count < 6)
|
||||||
return profile;
|
return profile;
|
||||||
|
|
||||||
|
unsigned int radius = std::max(smoothing_params.radius, (unsigned int)1);
|
||||||
std::vector<double> kernel = gauss_kernel(radius);
|
std::vector<double> kernel = gauss_kernel(radius);
|
||||||
int two_radius = 2 * (int)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]);
|
ret.push_back(profile[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// smooth the rest of the profile
|
// smooth the rest of the profile by biasing a gaussian blur
|
||||||
double med_h = 0.5 * (slicing_params.min_layer_height + slicing_params.max_layer_height);
|
// the bias moves the smoothed profile closer to the min_layer_height
|
||||||
double half_delta_h = 0.5 * (slicing_params.max_layer_height - slicing_params.min_layer_height);
|
double delta_h = 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;
|
double inv_delta_h = (delta_h != 0.0) ? 1.0 / delta_h : 1.0;
|
||||||
|
|
||||||
double max_dz_band = (double)radius * slicing_params.layer_height;
|
double max_dz_band = (double)radius * slicing_params.layer_height;
|
||||||
for (size_t i = skip_count; i < size; i += 2)
|
for (size_t i = skip_count; i < size; i += 2)
|
||||||
{
|
{
|
||||||
double zi = profile[i];
|
double zi = profile[i];
|
||||||
|
double hi = profile[i + 1];
|
||||||
ret.push_back(zi);
|
ret.push_back(zi);
|
||||||
ret.push_back(0.0);
|
ret.push_back(0.0);
|
||||||
double& height = ret.back();
|
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]);
|
double dz = std::abs(zi - profile[j]);
|
||||||
if (dz * slicing_params.layer_height <= max_dz_band)
|
if (dz * slicing_params.layer_height <= max_dz_band)
|
||||||
{
|
{
|
||||||
double dh = std::abs(profile[j + 1] - med_h);
|
double dh = std::abs(slicing_params.max_layer_height - profile[j + 1]);
|
||||||
double weight = kernel[kernel_id] * dh * inv_half_delta_h;
|
double weight = kernel[kernel_id] * sqrt(dh * inv_delta_h);
|
||||||
height += weight * profile[j + 1];
|
height += weight * profile[j + 1];
|
||||||
weight_total += weight;
|
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 ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
return gauss_blur(profile, std::max(radius, (unsigned int)1));
|
return gauss_blur(profile, smoothing_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjust_layer_height_profile(
|
void adjust_layer_height_profile(
|
||||||
|
@ -147,10 +147,18 @@ extern std::vector<double> layer_height_profile_adaptive(
|
|||||||
const SlicingParameters& slicing_params,
|
const SlicingParameters& slicing_params,
|
||||||
const ModelObject& object, float cusp_value);
|
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(
|
extern std::vector<double> smooth_height_profile(
|
||||||
const std::vector<double>& profile,
|
const std::vector<double>& profile, const SlicingParameters& slicing_params,
|
||||||
const SlicingParameters& slicing_params,
|
const HeightProfileSmoothingParams& smoothing_params);
|
||||||
unsigned int radius);
|
|
||||||
#else
|
#else
|
||||||
extern std::vector<coordf_t> layer_height_profile_adaptive(
|
extern std::vector<coordf_t> layer_height_profile_adaptive(
|
||||||
const SlicingParameters &slicing_params,
|
const SlicingParameters &slicing_params,
|
||||||
|
@ -132,7 +132,6 @@ GLCanvas3D::LayersEditing::LayersEditing()
|
|||||||
, m_layer_height_profile_modified(false)
|
, m_layer_height_profile_modified(false)
|
||||||
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
, m_adaptive_cusp(0.2f)
|
, m_adaptive_cusp(0.2f)
|
||||||
, m_smooth_radius(5)
|
|
||||||
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
, state(Unknown)
|
, state(Unknown)
|
||||||
, band_width(2.0f)
|
, band_width(2.0f)
|
||||||
@ -283,7 +282,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
|
|||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (imgui.button(_(L("Smooth"))))
|
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::SameLine();
|
||||||
ImGui::SetCursorPosX(text_align);
|
ImGui::SetCursorPosX(text_align);
|
||||||
@ -291,9 +290,16 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::PushItemWidth(120.0f);
|
ImGui::PushItemWidth(120.0f);
|
||||||
ImGui::SetCursorPosX(widget_align);
|
ImGui::SetCursorPosX(widget_align);
|
||||||
int radius = (int)m_smooth_radius;
|
int radius = (int)m_smooth_params.radius;
|
||||||
if (ImGui::SliderInt("##1", &radius, 1, 10))
|
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();
|
ImGui::Separator();
|
||||||
if (imgui.button(_(L("Reset"))))
|
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));
|
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;
|
const_cast<ModelObject*>(m_model_object)->layer_height_profile = m_layer_height_profile;
|
||||||
m_layers_texture.valid = false;
|
m_layers_texture.valid = false;
|
||||||
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
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
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
|
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
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
#if ENABLE_THUMBNAIL_GENERATOR
|
#if ENABLE_THUMBNAIL_GENERATOR
|
||||||
@ -1564,9 +1570,9 @@ void GLCanvas3D::adaptive_layer_height_profile(float cusp)
|
|||||||
m_dirty = true;
|
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_layers_editing.state = LayersEditing::Completed;
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,8 @@ template <size_t N> using Vec2dsEvent = ArrayEvent<Vec2d, N>;
|
|||||||
using Vec3dEvent = Event<Vec3d>;
|
using Vec3dEvent = Event<Vec3d>;
|
||||||
template <size_t N> using Vec3dsEvent = ArrayEvent<Vec3d, N>;
|
template <size_t N> using Vec3dsEvent = ArrayEvent<Vec3d, N>;
|
||||||
|
|
||||||
|
using HeightProfileSmoothEvent = Event<HeightProfileSmoothingParams>;
|
||||||
|
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent);
|
||||||
@ -107,7 +109,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
|
|||||||
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
|
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
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
class GLCanvas3D
|
class GLCanvas3D
|
||||||
@ -182,7 +184,7 @@ private:
|
|||||||
|
|
||||||
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
mutable float m_adaptive_cusp;
|
mutable float m_adaptive_cusp;
|
||||||
mutable unsigned int m_smooth_radius;
|
mutable HeightProfileSmoothingParams m_smooth_params;
|
||||||
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
class LayersTexture
|
class LayersTexture
|
||||||
@ -233,7 +235,7 @@ private:
|
|||||||
void reset_layer_height_profile(GLCanvas3D& canvas);
|
void reset_layer_height_profile(GLCanvas3D& canvas);
|
||||||
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
void adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp);
|
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
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
static float get_cursor_z_relative(const GLCanvas3D& canvas);
|
static float get_cursor_z_relative(const GLCanvas3D& canvas);
|
||||||
@ -531,7 +533,7 @@ public:
|
|||||||
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
void reset_layer_height_profile();
|
void reset_layer_height_profile();
|
||||||
void adaptive_layer_height_profile(float cusp);
|
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
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
bool is_reload_delayed() const;
|
bool is_reload_delayed() const;
|
||||||
|
@ -2090,7 +2090,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||||||
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
#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_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_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
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
// 3DScene/Toolbar:
|
// 3DScene/Toolbar:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user