diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs index 3aa2b0294..9ab12676e 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -1,4 +1,4 @@ -#version 110 +#version 130 const vec3 ZERO = vec3(0.0, 0.0, 0.0); //BBS: add grey and orange @@ -26,11 +26,29 @@ struct SlopeDetection mat3 volume_world_normal_matrix; }; +//BBS: add wireframe logic +varying vec3 barycentric_coordinates; +float edgeFactor(float lineWidth) { + vec3 d = fwidth(barycentric_coordinates); + vec3 a3 = smoothstep(vec3(0.0), d * lineWidth, barycentric_coordinates); + return min(min(a3.x, a3.y), a3.z); +} + +vec3 wireframe(vec3 fill, vec3 stroke, float lineWidth) { + return mix(stroke, fill, edgeFactor(lineWidth)); +} + +vec3 getWireframeColor(vec3 fill) { + float brightness = 0.2126 * fill.r + 0.7152 * fill.g + 0.0722 * fill.b; + return (brightness > 0.75) ? vec3(0.11, 0.165, 0.208) : vec3(0.988, 0.988, 0.988); +} + uniform vec4 uniform_color; uniform SlopeDetection slope; //BBS: add outline_color uniform bool is_outline; +uniform bool show_wireframe; uniform bool offset_depth_buffer; @@ -88,9 +106,17 @@ void main() else if (use_environment_tex) gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha); #endif - else - gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha); - + else { + //gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha); + if (show_wireframe) { + vec3 wireframeColor = show_wireframe ? getWireframeColor(color) : color; + vec3 triangleColor = wireframe(color, wireframeColor, 1.0); + gl_FragColor = vec4(vec3(intensity.y) + triangleColor * intensity.x, alpha); + } + else { + gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha); + } + } // In the support painting gizmo and the seam painting gizmo are painted triangles rendered over the already // rendered object. To resolved z-fighting between previously rendered object and painted triangles, values // inside the depth buffer are offset by small epsilon for painted triangles inside those gizmos. diff --git a/resources/shaders/gouraud.vs b/resources/shaders/gouraud.vs index 79d7a63c0..9d46b5c55 100644 --- a/resources/shaders/gouraud.vs +++ b/resources/shaders/gouraud.vs @@ -1,4 +1,4 @@ -#version 110 +#version 130 #define INTENSITY_CORRECTION 0.6 @@ -43,6 +43,8 @@ varying vec4 world_pos; varying float world_normal_z; varying vec3 eye_normal; +varying vec3 barycentric_coordinates; + void main() { // First transform the normal into camera space and normalize the result. @@ -70,4 +72,8 @@ void main() gl_Position = ftransform(); // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); + + //compute the Barycentric Coordinates + int vertexMod3 = gl_VertexID % 3; + barycentric_coordinates = vec3(float(vertexMod3 == 0), float(vertexMod3 == 1), float(vertexMod3 == 2)); } diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 8f48579a4..92f2eb9b3 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -869,6 +869,10 @@ void GLVolume::render(bool with_outline) const std::array body_color = { 1.0f, 1.0f, 1.0f, 1.0f }; //red shader->set_uniform("uniform_color", body_color); + if (GUI::wxGetApp().plater()->is_show_wireframe()) + shader->set_uniform("show_wireframe", true); + else + shader->set_uniform("show_wireframe", false); shader->set_uniform("is_outline", true); glsafe(::glPopMatrix()); glsafe(::glPushMatrix()); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3275d8100..969f370c1 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2662,6 +2662,12 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) #if !BBL_RELEASE_TO_PUBLIC wxGetApp().plater()->toggle_render_statistic_dialog(); m_dirty = true; +#endif + } + else if (evt.ShiftDown() && evt.ControlDown() && keyCode == WXK_RETURN) { +#if !BBL_RELEASE_TO_PUBLIC + wxGetApp().plater()->toggle_show_wireframe(); + m_dirty = true; #endif } else if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6bb2c65e4..90bcaeff4 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1612,6 +1612,7 @@ struct Plater::priv std::string label_btn_send; bool show_render_statistic_dialog{ false }; + bool show_wireframe{ false }; static const std::regex pattern_bundle; static const std::regex pattern_3mf; @@ -9039,7 +9040,7 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn, bool up wxBusyCursor wait; upload_job.printhost->get_groups(groups); } - + PrintHostSendDialog dlg(default_output_file, upload_job.printhost->get_post_upload_actions(), groups, upload_only); if (dlg.ShowModal() == wxID_OK) { upload_job.upload_data.upload_path = dlg.filename(); @@ -10509,6 +10510,16 @@ bool Plater::is_render_statistic_dialog_visible() const return p->show_render_statistic_dialog; } +void Plater::toggle_show_wireframe() +{ + p->show_wireframe = !p->show_wireframe; +} + +bool Plater::is_show_wireframe() const +{ + return p->show_wireframe; +} + /*Plater::TakeSnapshot::TakeSnapshot(Plater *plater, const std::string &snapshot_name) : TakeSnapshot(plater, from_u8(snapshot_name)) {} diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index ab1e7e571..1d61f068f 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -618,6 +618,9 @@ public: void toggle_render_statistic_dialog(); bool is_render_statistic_dialog_visible() const; + void toggle_show_wireframe(); + bool is_show_wireframe() const; + // Wrapper around wxWindow::PopupMenu to suppress error messages popping out while tracking the popup menu. bool PopupMenu(wxMenu *menu, const wxPoint& pos = wxDefaultPosition); bool PopupMenu(wxMenu *menu, int x, int y) { return this->PopupMenu(menu, wxPoint(x, y)); }