From d99ea7c20f0269f3dc5def996d127aceec687a4b Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Wed, 28 Jul 2021 11:21:59 +0200
Subject: [PATCH] Tech ENABLE_SINKING_CONTOURS -> Sinking contours rendered
 using triangles

---
 src/slic3r/GUI/3DScene.cpp           | 48 +++++++++++++++++++++-------
 src/slic3r/GUI/3DScene.hpp           |  1 +
 src/slic3r/GUI/GLCanvas3D.cpp        |  8 ++---
 src/slic3r/GUI/Gizmos/GLGizmoCut.cpp |  1 +
 4 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp
index c416bbabc..63fe333d7 100644
--- a/src/slic3r/GUI/3DScene.cpp
+++ b/src/slic3r/GUI/3DScene.cpp
@@ -24,6 +24,9 @@
 #include "libslic3r/Utils.hpp"
 #include "libslic3r/AppConfig.hpp"
 #include "libslic3r/PresetBundle.hpp"
+#if ENABLE_SINKING_CONTOURS
+#include "libslic3r/Tesselate.hpp"
+#endif // ENABLE_SINKING_CONTOURS
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -285,6 +288,8 @@ void GLIndexedVertexArray::render(
 }
 
 #if ENABLE_SINKING_CONTOURS
+const float GLVolume::SinkingContours::HalfWidth = 0.25f;
+
 void GLVolume::SinkingContours::update()
 {
     if (m_parent.is_sinking() && !m_parent.is_below_printbed()) {
@@ -301,14 +306,35 @@ void GLVolume::SinkingContours::update()
             Polygons polygons = slice_mesh(mesh.its, 0.0f, slicing_params);
 
             m_model.reset();
-            m_model.init_from(polygons, 0.0f);
-            std::array<float, 4> color = {
-                1.0f - m_parent.render_color[0],
-                1.0f - m_parent.render_color[1],
-                1.0f - m_parent.render_color[2],
-                m_parent.render_color[3]
-            };
-            m_model.set_color(-1, color);
+            GUI::GLModel::InitializationData init_data;
+            for (const Polygon& polygon : polygons) {
+                const Polygons outer_polys = offset(polygon, float(scale_(HalfWidth)));
+                const Polygons inner_polys = offset(polygon, -float(scale_(HalfWidth)));
+
+                if (outer_polys.empty())
+                    // no outer contour, skip
+                    continue;
+
+                const ExPolygons diff_polys_ex = diff_ex(outer_polys, inner_polys);
+
+                for (const ExPolygon& poly : diff_polys_ex) {
+                    GUI::GLModel::InitializationData::Entity entity;
+                    entity.type = GUI::GLModel::PrimitiveType::Triangles;
+                    const std::vector<Vec3d> triangulation = triangulate_expolygon_3d(poly);
+                    for (const Vec3d& v : triangulation) {
+                        entity.positions.emplace_back(v.cast<float>() + Vec3f(0.0f, 0.0f, 0.015f)); // add a small positive z to avoid z-fighting
+                        entity.normals.emplace_back(Vec3f::UnitZ());
+                        const size_t positions_count = entity.positions.size();
+                        if (positions_count % 3 == 0) {
+                            entity.indices.emplace_back(positions_count - 3);
+                            entity.indices.emplace_back(positions_count - 2);
+                            entity.indices.emplace_back(positions_count - 1);
+                        }
+                    }
+                    init_data.entities.emplace_back(entity);
+                }
+            }
+            m_model.init_from(init_data);
         }
         else
             m_shift = box.center() - m_old_box.center();
@@ -831,7 +857,6 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
         if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
             volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) {
             shader->stop_using();
-            glsafe(::glLineWidth(5.0f));
             volume.first->update_sinking_contours_color();
             volume.first->render_sinking_contours();
             shader->start_using();
@@ -879,11 +904,10 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
         if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
             (volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) {
             shader->stop_using();
-            glsafe(::glLineWidth(5.0f));
-            glsafe(::glDisable(GL_DEPTH_TEST));
+            glsafe(::glDepthFunc(GL_ALWAYS));
             volume.first->update_sinking_contours_color();
             volume.first->render_sinking_contours();
-            glsafe(::glEnable(GL_DEPTH_TEST));
+            glsafe(::glDepthFunc(GL_LESS));
             shader->start_using();
         }
     }
diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp
index f61df9294..1e1668dcd 100644
--- a/src/slic3r/GUI/3DScene.hpp
+++ b/src/slic3r/GUI/3DScene.hpp
@@ -284,6 +284,7 @@ private:
 #if ENABLE_SINKING_CONTOURS
     class SinkingContours
     {
+        static const float HalfWidth;
         GLVolume& m_parent;
         GUI::GLModel m_model;
         BoundingBoxf3 m_old_box;
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 39213dc2c..87b487e6a 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -792,7 +792,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
     for (const Polygon& poly : polygons) {
         triangles_count += poly.points.size() - 2;
     }
-    size_t vertices_count = 3 * triangles_count;
+    const size_t vertices_count = 3 * triangles_count;
 
     if (m_render_fill) {
         GLModel::InitializationData fill_data;
@@ -803,13 +803,13 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
         entity.normals.reserve(vertices_count);
         entity.indices.reserve(vertices_count);
 
-        ExPolygons polygons_union = union_ex(polygons);
+        const ExPolygons polygons_union = union_ex(polygons);
         for (const ExPolygon& poly : polygons_union) {
-            std::vector<Vec3d> triangulation = triangulate_expolygon_3d(poly, false);
+            const std::vector<Vec3d> triangulation = triangulate_expolygon_3d(poly);
             for (const Vec3d& v : triangulation) {
                 entity.positions.emplace_back(v.cast<float>() + Vec3f(0.0f, 0.0f, 0.0125f)); // add a small positive z to avoid z-fighting
                 entity.normals.emplace_back(Vec3f::UnitZ());
-                size_t positions_count = entity.positions.size();
+                const size_t positions_count = entity.positions.size();
                 if (positions_count % 3 == 0) {
                     entity.indices.emplace_back(positions_count - 3);
                     entity.indices.emplace_back(positions_count - 2);
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
index d6ebc0dd3..30e40b5e5 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
@@ -142,6 +142,7 @@ void GLGizmoCut::on_render()
 #if ENABLE_SINKING_CONTOURS
     glsafe(::glPushMatrix());
     glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z()));
+    glsafe(::glLineWidth(2.0f));
     m_cut_contours.contours.render();
     glsafe(::glPopMatrix());
 #endif // ENABLE_SINKING_CONTOURS