Merge remote-tracking branch 'remotes/origin/et_slope_shader'

This commit is contained in:
bubnikv 2020-03-25 16:09:04 +01:00
commit 750e704b37
12 changed files with 281 additions and 19 deletions

View file

@ -1,6 +1,21 @@
#version 110
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
const vec3 GREEN = vec3(0.0, 0.7, 0.0);
const vec3 YELLOW = vec3(0.5, 0.7, 0.0);
const vec3 RED = vec3(0.7, 0.0, 0.0);
const float EPSILON = 0.0001;
struct SlopeDetection
{
bool active;
// x = yellow, y = red
vec2 z_range;
mat3 volume_world_normal_matrix;
};
uniform vec4 uniform_color;
uniform SlopeDetection slope;
varying vec3 clipping_planes_dots;
@ -10,14 +25,20 @@ varying vec2 intensity;
varying vec3 delta_box_min;
varying vec3 delta_box_max;
uniform vec4 uniform_color;
varying float world_normal_z;
vec3 slope_color()
{
float gradient_range = slope.z_range.x - slope.z_range.y;
return (world_normal_z > slope.z_range.x - EPSILON) ? GREEN : ((gradient_range == 0.0) ? RED : mix(RED, YELLOW, clamp((world_normal_z - slope.z_range.y) / gradient_range, 0.0, 1.0)));
}
void main()
{
if (any(lessThan(clipping_planes_dots, ZERO)))
discard;
vec3 color = slope.active ? slope_color() : uniform_color.rgb;
// if the fragment is outside the print volume -> use darker color
vec3 color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(uniform_color.rgb, ZERO, 0.3333) : uniform_color.rgb;
color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + color * intensity.x, uniform_color.a);
}

View file

@ -20,13 +20,22 @@ const vec3 ZERO = vec3(0.0, 0.0, 0.0);
struct PrintBoxDetection
{
bool active;
vec3 min;
vec3 max;
bool volume_detection;
mat4 volume_world_matrix;
};
struct SlopeDetection
{
bool active;
// x = yellow, y = red
vec2 z_range;
mat3 volume_world_normal_matrix;
};
uniform PrintBoxDetection print_box;
uniform SlopeDetection slope;
// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
uniform vec2 z_range;
@ -41,6 +50,8 @@ varying vec3 delta_box_max;
varying vec3 clipping_planes_dots;
varying float world_normal_z;
void main()
{
// First transform the normal into camera space and normalize the result.
@ -61,7 +72,7 @@ void main()
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
// compute deltas for out of print volume detection (world coordinates)
if (print_box.volume_detection)
if (print_box.active)
{
vec3 v = (print_box.volume_world_matrix * gl_Vertex).xyz;
delta_box_min = v - print_box.min;
@ -73,6 +84,9 @@ void main()
delta_box_max = ZERO;
}
// z component of normal vector in world coordinate used for slope shading
world_normal_z = slope.active ? (normalize(slope.volume_world_normal_matrix * gl_Normal)).z : 0.0;
gl_Position = ftransform();
// Point in homogenous coordinates.
vec4 world_pos = print_box.volume_world_matrix * gl_Vertex;

View file

@ -44,6 +44,13 @@
// Enable fix for dragging mouse event handling for gizmobar
#define ENABLE_GIZMO_TOOLBAR_DRAGGING_FIX (1 && ENABLE_2_2_0_FINAL)
//============
// 2.3.0 techs
//============
#define ENABLE_2_3_0 1
// Enable rendering of objects colored by facets' slope
#define ENABLE_SLOPE_RENDERING (1 && ENABLE_2_2_0)
//===================
// 2.3.0.alpha1 techs

View file

@ -394,6 +394,7 @@ void GLVolume::render() const
glFrontFace(GL_CCW);
}
#if !ENABLE_SLOPE_RENDERING
void GLVolume::render(int color_id, int detection_id, int worldmatrix_id) const
{
if (color_id >= 0)
@ -409,6 +410,7 @@ void GLVolume::render(int color_id, int detection_id, int worldmatrix_id) const
render();
}
#endif // !ENABLE_SLOPE_RENDERING
bool GLVolume::is_sla_support() const { return this->composite_id.volume_id == -int(slaposSupportTree); }
bool GLVolume::is_sla_pad() const { return this->composite_id.volume_id == -int(slaposPad); }
@ -650,28 +652,64 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1;
GLint z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "z_range") : -1;
GLint clipping_plane_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "clipping_plane") : -1;
GLint print_box_min_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.min") : -1;
GLint print_box_max_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.max") : -1;
GLint print_box_detection_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1;
GLint print_box_active_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.active") : -1;
GLint print_box_worldmatrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1;
#if ENABLE_SLOPE_RENDERING
GLint slope_active_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "slope.active") : -1;
GLint slope_normal_matrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "slope.volume_world_normal_matrix") : -1;
GLint slope_z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "slope.z_range") : -1;
#endif // ENABLE_SLOPE_RENDERING
glcheck();
if (print_box_min_id != -1)
glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min));
glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)m_print_box_min));
if (print_box_max_id != -1)
glsafe(::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max));
glsafe(::glUniform3fv(print_box_max_id, 1, (const GLfloat*)m_print_box_max));
if (z_range_id != -1)
glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range));
glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)m_z_range));
if (clipping_plane_id != -1)
glsafe(::glUniform4fv(clipping_plane_id, 1, (const GLfloat*)clipping_plane));
glsafe(::glUniform4fv(clipping_plane_id, 1, (const GLfloat*)m_clipping_plane));
#if ENABLE_SLOPE_RENDERING
if (slope_z_range_id != -1)
glsafe(::glUniform2fv(slope_z_range_id, 1, (const GLfloat*)m_slope.z_range.data()));
#endif // ENABLE_SLOPE_RENDERING
GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
for (GLVolumeWithIdAndZ& volume : to_render) {
volume.first->set_render_color();
#if ENABLE_SLOPE_RENDERING
if (color_id >= 0)
glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)volume.first->render_color));
else
glsafe(::glColor4fv(volume.first->render_color));
if (print_box_active_id != -1)
glsafe(::glUniform1i(print_box_active_id, volume.first->shader_outside_printer_detection_enabled ? 1 : 0));
if (print_box_worldmatrix_id != -1)
glsafe(::glUniformMatrix4fv(print_box_worldmatrix_id, 1, GL_FALSE, (const GLfloat*)volume.first->world_matrix().cast<float>().data()));
if (slope_active_id != -1)
glsafe(::glUniform1i(slope_active_id, m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower ? 1 : 0));
if (slope_normal_matrix_id != -1)
{
Matrix3f normal_matrix = volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>();
glsafe(::glUniformMatrix3fv(slope_normal_matrix_id, 1, GL_FALSE, (const GLfloat*)normal_matrix.data()));
}
volume.first->render();
#else
volume.first->render(color_id, print_box_detection_id, print_box_worldmatrix_id);
#endif // ENABLE_SLOPE_RENDERING
}
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
@ -1887,7 +1925,16 @@ void GLModel::render() const
GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1;
glcheck();
#if ENABLE_SLOPE_RENDERING
if (color_id >= 0)
glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)m_volume.render_color));
else
glsafe(::glColor4fv(m_volume.render_color));
m_volume.render();
#else
m_volume.render(color_id, -1, -1);
#endif // ENABLE_SLOPE_RENDERING
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));

View file

@ -445,7 +445,9 @@ public:
void set_range(double low, double high);
void render() const;
#if !ENABLE_SLOPE_RENDERING
void render(int color_id, int detection_id, int worldmatrix_id) const;
#endif // !ENABLE_SLOPE_RENDERING
void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); }
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
@ -481,20 +483,36 @@ public:
private:
// min and max vertex of the print box volume
float print_box_min[3];
float print_box_max[3];
float m_print_box_min[3];
float m_print_box_max[3];
// z range for clipping in shaders
float z_range[2];
float m_z_range[2];
// plane coeffs for clipping in shaders
float clipping_plane[4];
float m_clipping_plane[4];
#if ENABLE_SLOPE_RENDERING
struct Slope
{
// toggle for slope rendering
bool active{ false };
// [0] = yellow, [1] = red
std::array<float, 2> z_range;
};
Slope m_slope;
#endif // ENABLE_SLOPE_RENDERING
public:
GLVolumePtrs volumes;
GLVolumeCollection() {};
~GLVolumeCollection() { clear(); };
#if ENABLE_SLOPE_RENDERING
GLVolumeCollection() { set_default_slope_z_range(); }
#else
GLVolumeCollection() = default;
#endif // ENABLE_SLOPE_RENDERING
~GLVolumeCollection() { clear(); }
std::vector<int> load_object(
const ModelObject *model_object,
@ -545,12 +563,21 @@ public:
void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); }
void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) {
print_box_min[0] = min_x; print_box_min[1] = min_y; print_box_min[2] = min_z;
print_box_max[0] = max_x; print_box_max[1] = max_y; print_box_max[2] = max_z;
m_print_box_min[0] = min_x; m_print_box_min[1] = min_y; m_print_box_min[2] = min_z;
m_print_box_max[0] = max_x; m_print_box_max[1] = max_y; m_print_box_max[2] = max_z;
}
void set_z_range(float min_z, float max_z) { z_range[0] = min_z; z_range[1] = max_z; }
void set_clipping_plane(const double* coeffs) { clipping_plane[0] = coeffs[0]; clipping_plane[1] = coeffs[1]; clipping_plane[2] = coeffs[2]; clipping_plane[3] = coeffs[3]; }
void set_z_range(float min_z, float max_z) { m_z_range[0] = min_z; m_z_range[1] = max_z; }
void set_clipping_plane(const double* coeffs) { m_clipping_plane[0] = coeffs[0]; m_clipping_plane[1] = coeffs[1]; m_clipping_plane[2] = coeffs[2]; m_clipping_plane[3] = coeffs[3]; }
#if ENABLE_SLOPE_RENDERING
bool is_slope_active() const { return m_slope.active; }
void set_slope_active(bool active) { m_slope.active = active; }
const std::array<float, 2>& get_slope_z_range() const { return m_slope.z_range; }
void set_slope_z_range(const std::array<float, 2>& range) { m_slope.z_range = range; }
void set_default_slope_z_range() { m_slope.z_range = { -::cos(Geometry::deg2rad(90.0f - 45.0f)), -::cos(Geometry::deg2rad(90.0f - 70.0f)) }; }
#endif // ENABLE_SLOPE_RENDERING
// returns true if all the volumes are completely contained in the print volume
// returns the containment state in the given out_state, if non-null

View file

@ -1445,6 +1445,62 @@ void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas
}
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
#if ENABLE_SLOPE_RENDERING
void GLCanvas3D::Slope::render() const
{
if (is_shown())
{
const std::array<float, 2>& z_range = m_volumes.get_slope_z_range();
std::array<float, 2> angle_range = { Geometry::rad2deg(::acos(z_range[0])) - 90.0f, Geometry::rad2deg(::acos(z_range[1])) - 90.0f };
bool modified = false;
ImGuiWrapper& imgui = *wxGetApp().imgui();
const Size& cnv_size = m_canvas.get_canvas_size();
imgui.set_next_window_pos((float)cnv_size.get_width(), (float)cnv_size.get_height(), ImGuiCond_Always, 1.0f, 1.0f);
imgui.begin(_(L("Slope visualization")), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
imgui.text(_(L("Facets' normal angle range (degrees)")) + ":");
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.75f, 0.75f, 0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(1.0f, 1.0f, 0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(0.85f, 0.85f, 0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(0.25f, 0.25f, 0.0f, 1.0f));
if (ImGui::SliderFloat("##yellow", &angle_range[0], 0.0f, 90.0f, "%.1f"))
{
modified = true;
if (angle_range[1] < angle_range[0])
angle_range[1] = angle_range[0];
}
ImGui::PopStyleColor(4);
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.75f, 0.0f, 0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(1.0f, 0.0f, 0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(0.85f, 0.0f, 0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(0.25f, 0.0f, 0.0f, 1.0f));
if (ImGui::SliderFloat("##red", &angle_range[1], 0.0f, 90.0f, "%.1f"))
{
modified = true;
if (angle_range[0] > angle_range[1])
angle_range[0] = angle_range[1];
}
ImGui::PopStyleColor(4);
ImGui::Separator();
if (imgui.button(_(L("Default"))))
m_volumes.set_default_slope_z_range();
// to let the dialog immediately showup without waiting for a mouse move
if (ImGui::GetWindowContentRegionWidth() + 2.0f * ImGui::GetStyle().WindowPadding.x != ImGui::CalcWindowExpectedSize(ImGui::GetCurrentWindow()).x)
m_canvas.request_extra_frame();
imgui.end();
if (modified)
m_volumes.set_slope_z_range({ -::cos(Geometry::deg2rad(90.0f - angle_range[0])), -::cos(Geometry::deg2rad(90.0f - angle_range[1])) });
}
}
#endif // ENABLE_SLOPE_RENDERING
wxDEFINE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent);
@ -1519,6 +1575,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar
#endif // ENABLE_RENDER_PICKING_PASS
, m_render_sla_auxiliaries(true)
, m_labels(*this)
#if ENABLE_SLOPE_RENDERING
, m_slope(*this, m_volumes)
#endif // ENABLE_SLOPE_RENDERING
{
if (m_canvas != nullptr) {
m_timer.SetOwner(m_canvas);
@ -1838,6 +1897,11 @@ bool GLCanvas3D::is_reload_delayed() const
void GLCanvas3D::enable_layers_editing(bool enable)
{
#if ENABLE_SLOPE_RENDERING
if (enable && m_slope.is_shown())
m_slope.show(false);
#endif // ENABLE_SLOPE_RENDERING
m_layers_editing.set_enabled(enable);
const Selection::IndicesList& idxs = m_selection.get_volume_idxs();
for (unsigned int idx : idxs)
@ -3022,6 +3086,17 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
case 'B':
case 'b': { zoom_to_bed(); break; }
#if ENABLE_SLOPE_RENDERING
case 'D':
case 'd': {
if (!is_layers_editing_enabled())
{
m_slope.show(!m_slope.is_shown());
m_dirty = true;
}
break;
}
#endif // ENABLE_SLOPE_RENDERING
case 'E':
case 'e': { m_labels.show(!m_labels.is_shown()); m_dirty = true; break; }
case 'I':
@ -5413,6 +5488,10 @@ void GLCanvas3D::_render_overlays() const
}
m_labels.render(sorted_instances);
#if ENABLE_SLOPE_RENDERING
m_slope.render();
#endif // ENABLE_SLOPE_RENDERING
glsafe(::glPopMatrix());
}

View file

@ -406,6 +406,24 @@ private:
};
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
#if ENABLE_SLOPE_RENDERING
class Slope
{
bool m_enabled{ false };
GLCanvas3D& m_canvas;
GLVolumeCollection& m_volumes;
public:
Slope(GLCanvas3D& canvas, GLVolumeCollection& volumes) : m_canvas(canvas), m_volumes(volumes) {}
void enable(bool enable) { m_enabled = enable; }
bool is_enabled() const { return m_enabled; }
void show(bool show) { m_volumes.set_slope_active(m_enabled ? show : false); }
bool is_shown() const { return m_volumes.is_slope_active(); }
void render() const;
};
#endif // ENABLE_SLOPE_RENDERING
public:
enum ECursorType : unsigned char
{
@ -489,6 +507,9 @@ private:
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
mutable Tooltip m_tooltip;
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
#if ENABLE_SLOPE_RENDERING
Slope m_slope;
#endif // ENABLE_SLOPE_RENDERING
public:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
@ -579,6 +600,9 @@ public:
void enable_undoredo_toolbar(bool enable);
void enable_dynamic_background(bool enable);
void enable_labels(bool enable) { m_labels.enable(enable); }
#if ENABLE_SLOPE_RENDERING
void enable_slope(bool enable) { m_slope.enable(enable); }
#endif // ENABLE_SLOPE_RENDERING
void allow_multisample(bool allow);
void zoom_to_bed();
@ -702,6 +726,11 @@ public:
bool are_labels_shown() const { return m_labels.is_shown(); }
void show_labels(bool show) { m_labels.show(show); }
#if ENABLE_SLOPE_RENDERING
bool is_slope_shown() const { return m_slope.is_shown(); }
void show_slope(bool show) { m_slope.show(show); }
#endif // ENABLE_SLOPE_RENDERING
private:
bool _is_shown_on_screen() const;

View file

@ -98,6 +98,9 @@ bool View3D::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_
m_canvas->enable_main_toolbar(true);
m_canvas->enable_undoredo_toolbar(true);
m_canvas->enable_labels(true);
#if ENABLE_SLOPE_RENDERING
m_canvas->enable_slope(true);
#endif // ENABLE_SLOPE_RENDERING
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);

View file

@ -145,6 +145,9 @@ void KBShortcutsDialog::fill_shortcuts()
// View
{ "0-6", L("Camera view") },
{ "E", L("Show/Hide object/instance labels") },
#if ENABLE_SLOPE_RENDERING
{ "D", L("Turn On/Off facets' slope rendering") },
#endif // ENABLE_SLOPE_RENDERING
// Configuration
{ ctrl + "P", L("Preferences") },
// Help

View file

@ -764,9 +764,20 @@ void MainFrame::init_menubar()
append_menu_item(viewMenu, wxID_ANY, _(L("Right")) + sep + "&6", _(L("Right View")), [this](wxCommandEvent&) { select_view("right"); },
"", nullptr, [this](){return can_change_view(); }, this);
viewMenu->AppendSeparator();
#if ENABLE_SLOPE_RENDERING
wxMenu* options_menu = new wxMenu();
append_menu_check_item(options_menu, wxID_ANY, _(L("Show &labels")) + sep + "E", _(L("Show object/instance labels in 3D scene")),
[this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); }, this,
[this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_labels_shown(); }, this);
append_menu_check_item(options_menu, wxID_ANY, _(L("Show &slope")) + sep + "D", _(L("Objects coloring using faces' slope")),
[this](wxCommandEvent&) { m_plater->show_view3D_slope(!m_plater->is_view3D_slope_shown()); }, this,
[this]() { return m_plater->is_view3D_shown() && !m_plater->is_view3D_layers_editing_enabled(); }, [this]() { return m_plater->is_view3D_slope_shown(); }, this);
append_submenu(viewMenu, options_menu, wxID_ANY, _(L("&Options")), "");
#else
append_menu_check_item(viewMenu, wxID_ANY, _(L("Show &labels")) + sep + "E", _(L("Show object/instance labels in 3D scene")),
[this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); }, this,
[this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_labels_shown(); }, this);
#endif // ENABLE_SLOPE_RENDERING
}
// Help menu

View file

@ -1823,6 +1823,13 @@ struct Plater::priv
bool are_view3D_labels_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->are_labels_shown(); }
void show_view3D_labels(bool show) { if (current_panel == view3D) view3D->get_canvas3d()->show_labels(show); }
#if ENABLE_SLOPE_RENDERING
bool is_view3D_slope_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->is_slope_shown(); }
void show_view3D_slope(bool show) { if (current_panel == view3D) view3D->get_canvas3d()->show_slope(show); }
bool is_view3D_layers_editing_enabled() const { return (current_panel == view3D) && view3D->get_canvas3d()->is_layers_editing_enabled(); }
#endif // ENABLE_SLOPE_RENDERING
void set_current_canvas_as_dirty();
GLCanvas3D* get_current_canvas3D();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
@ -4674,6 +4681,13 @@ bool Plater::is_view3D_shown() const { return p->is_view3D_shown(); }
bool Plater::are_view3D_labels_shown() const { return p->are_view3D_labels_shown(); }
void Plater::show_view3D_labels(bool show) { p->show_view3D_labels(show); }
#if ENABLE_SLOPE_RENDERING
bool Plater::is_view3D_slope_shown() const { return p->is_view3D_slope_shown(); }
void Plater::show_view3D_slope(bool show) { p->show_view3D_slope(show); }
bool Plater::is_view3D_layers_editing_enabled() const { return p->is_view3D_layers_editing_enabled(); }
#endif // ENABLE_SLOPE_RENDERING
void Plater::select_all() { p->select_all(); }
void Plater::deselect_all() { p->deselect_all(); }

View file

@ -175,6 +175,13 @@ public:
bool are_view3D_labels_shown() const;
void show_view3D_labels(bool show);
#if ENABLE_SLOPE_RENDERING
bool is_view3D_slope_shown() const;
void show_view3D_slope(bool show);
bool is_view3D_layers_editing_enabled() const;
#endif // ENABLE_SLOPE_RENDERING
// Called after the Preferences dialog is closed and the program settings are saved.
// Update the UI based on the current preferences.
void update_ui_from_settings();