From f26ec7feb37c9a088b99e9df74922e0d15ede149 Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Tue, 8 Jan 2019 14:03:41 +0100
Subject: [PATCH] pad wall smoothing only for the top of the wall.

---
 src/libslic3r/SLA/SLABasePool.cpp | 195 +++++++++---------------------
 1 file changed, 55 insertions(+), 140 deletions(-)

diff --git a/src/libslic3r/SLA/SLABasePool.cpp b/src/libslic3r/SLA/SLABasePool.cpp
index 5dbbb0440..fb68ae1d0 100644
--- a/src/libslic3r/SLA/SLABasePool.cpp
+++ b/src/libslic3r/SLA/SLABasePool.cpp
@@ -215,41 +215,67 @@ inline Contour3D roofs(const ExPolygon& poly, coord_t z_distance) {
     return lower;
 }
 
-template<class ExP, class D>
 Contour3D round_edges(const ExPolygon& base_plate,
                       double radius_mm,
                       double degrees,
                       double ceilheight_mm,
                       bool dir,
                       ThrowOnCancel throw_on_cancel,
-                      ExP&& last_offset = ExP(), D&& last_height = D())
+                      ExPolygon& last_offset, double& last_height)
 {
     auto ob = base_plate;
     auto ob_prev = ob;
     double wh = ceilheight_mm, wh_prev = wh;
     Contour3D curvedwalls;
 
-    int steps = 15; // int(std::ceil(10*std::pow(radius_mm, 1.0/3)));
+    int steps = 30;
     double stepx = radius_mm / steps;
     coord_t s = dir? 1 : -1;
     degrees = std::fmod(degrees, 180);
 
-    if(degrees >= 90) {
-        for(int i = 1; i <= steps; ++i) {
-            throw_on_cancel();
+    // we use sin for x distance because we interpret the angle starting from
+    // PI/2
+    int tos = degrees < 90?
+               int(radius_mm*std::cos(degrees * PI / 180 - PI/2) / stepx) : steps;
 
+    for(int i = 1; i <= tos; ++i) {
+        throw_on_cancel();
+
+        ob = base_plate;
+
+        double r2 = radius_mm * radius_mm;
+        double xx = i*stepx;
+        double x2 = xx*xx;
+        double stepy = std::sqrt(r2 - x2);
+
+        offset(ob, s*mm(xx));
+        wh = ceilheight_mm - radius_mm + stepy;
+
+        Contour3D pwalls;
+        pwalls = walls(ob, ob_prev, wh, wh_prev, throw_on_cancel);
+
+        curvedwalls.merge(pwalls);
+        ob_prev = ob;
+        wh_prev = wh;
+    }
+
+    if(degrees > 90) {
+        double tox = radius_mm - radius_mm*std::cos(degrees * PI / 180 - PI/2);
+        int tos = int(tox / stepx);
+
+        for(int i = 1; i <= tos; ++i) {
+            throw_on_cancel();
             ob = base_plate;
 
             double r2 = radius_mm * radius_mm;
-            double xx = i*stepx;
+            double xx = radius_mm - i*stepx;
             double x2 = xx*xx;
             double stepy = std::sqrt(r2 - x2);
-
             offset(ob, s*mm(xx));
-            wh = ceilheight_mm - radius_mm + stepy;
+            wh = ceilheight_mm - radius_mm - stepy;
 
             Contour3D pwalls;
-            pwalls = walls(ob, ob_prev, wh, wh_prev, throw_on_cancel);
+            pwalls = walls(ob_prev, ob, wh_prev, wh, throw_on_cancel);
 
             curvedwalls.merge(pwalls);
             ob_prev = ob;
@@ -257,28 +283,6 @@ Contour3D round_edges(const ExPolygon& base_plate,
         }
     }
 
-    double tox = radius_mm - radius_mm*std::sin(degrees * PI / 180);
-    int tos = int(tox / stepx);
-
-    for(int i = 1; i <= tos; ++i) {
-        throw_on_cancel();
-        ob = base_plate;
-
-        double r2 = radius_mm * radius_mm;
-        double xx = radius_mm - i*stepx;
-        double x2 = xx*xx;
-        double stepy = std::sqrt(r2 - x2);
-        offset(ob, s*mm(xx));
-        wh = ceilheight_mm - radius_mm - stepy;
-
-        Contour3D pwalls;
-        pwalls = walls(ob_prev, ob, wh_prev, wh, throw_on_cancel);
-
-        curvedwalls.merge(pwalls);
-        ob_prev = ob;
-        wh_prev = wh;
-    }
-
     last_offset = std::move(ob);
     last_height = wh;
 
@@ -543,23 +547,33 @@ void create_base_pool(const ExPolygons &ground_layer, TriangleMesh& out,
 
 
         // Generate the smoothed edge geometry
-        auto curvedwalls = round_edges(ob,
-                                       r,
-                                       phi,  // 170 degrees
-                                       0,    // z position of the input plane
-                                       true,
-                                       thrcl,
-                                       ob, wh);
-        pool.merge(curvedwalls);
+        auto walledges = round_edges(ob,
+                                     r,
+                                     phi,  // 170 degrees
+                                     0,    // z position of the input plane
+                                     true,
+                                     thrcl,
+                                     ob, wh);
+        pool.merge(walledges);
 
         // Now that we have the rounded edge connencting the top plate with
         // the outer side walls, we can generate and merge the sidewall geometry
         auto pwalls = walls(ob, inner_base, wh, -fullheight, thrcl);
         pool.merge(pwalls);
 
+        // Generate the smoothed edge geometry
+        auto cavityedges = round_edges(middle_base,
+                                       r,
+                                       phi - 90,  // 170 degrees
+                                       0,    // z position of the input plane
+                                       false,
+                                       thrcl,
+                                       ob, wh);
+        pool.merge(cavityedges);
+
         // Next is the cavity walls connecting to the top plate's artificially
         // created hole.
-        auto cavitywalls = walls(inner_base, middle_base, -wingheight, 0, thrcl);
+        auto cavitywalls = walls(inner_base, ob, -wingheight, wh, thrcl);
         pool.merge(cavitywalls);
 
         // Now we need to triangulate the top and bottom plates as well as the
@@ -580,105 +594,6 @@ void create_base_pool(const ExPolygons &ground_layer, TriangleMesh& out,
 
         out.merge(mesh(pool));
     }
-
-//    double mdist = 2*(1.8*cfg.min_wall_thickness_mm + 4*cfg.edge_radius_mm) +
-//                   cfg.max_merge_distance_mm;
-
-//    auto concavehs = concave_hull(ground_layer, mdist, cfg.throw_on_cancel);
-//    for(ExPolygon& concaveh : concavehs) {
-//        if(concaveh.contour.points.empty()) return;
-//        concaveh.holes.clear();
-
-//        const coord_t WALL_THICKNESS = mm(cfg.min_wall_thickness_mm);
-
-//        const coord_t WALL_DISTANCE = mm(2*cfg.edge_radius_mm) +
-//                                      coord_t(0.8*WALL_THICKNESS);
-
-//        const coord_t HEIGHT = mm(cfg.min_wall_height_mm);
-
-//        auto outer_base = concaveh;
-//        offset(outer_base, WALL_THICKNESS+WALL_DISTANCE);
-//        auto inner_base = outer_base;
-//        offset(inner_base, -WALL_THICKNESS);
-//        inner_base.holes.clear(); outer_base.holes.clear();
-
-//        ExPolygon top_poly;
-//        top_poly.contour = outer_base.contour;
-//        top_poly.holes.emplace_back(inner_base.contour);
-//        auto& tph = top_poly.holes.back().points;
-//        std::reverse(tph.begin(), tph.end());
-
-//        Contour3D pool;
-
-//        ExPolygon ob = outer_base; double wh = 0;
-
-//        // now we will calculate the angle or portion of the circle from
-//        // pi/2 that will connect perfectly with the bottom plate.
-//        // this is a tangent point calculation problem and the equation can
-//        // be found for example here:
-//        // http://www.ambrsoft.com/TrigoCalc/Circles2/CirclePoint/CirclePointDistance.htm
-//        // the y coordinate would be:
-//        // y = cy + (r^2*py - r*px*sqrt(px^2 + py^2 - r^2) / (px^2 + py^2)
-//        // where px and py are the coordinates of the point outside the circle
-//        // cx and cy are the circle center, r is the radius
-//        // to get the angle we use arcsin function and subtract 90 degrees then
-//        // flip the sign to get the right input to the round_edge function.
-//        double r = cfg.edge_radius_mm;
-//        double cy = 0;
-//        double cx = 0;
-//        double px = cfg.min_wall_thickness_mm;
-//        double py = r - cfg.min_wall_height_mm;
-
-//        double pxcx = px - cx;
-//        double pycy = py - cy;
-//        double b_2 = pxcx*pxcx + pycy*pycy;
-//        double r_2 = r*r;
-//        double D = std::sqrt(b_2 - r_2);
-//        double vy = (r_2*pycy - r*pxcx*D) / b_2;
-//        double phi = -(std::asin(vy/r) * 180 / PI - 90);
-
-//        auto curvedwalls = round_edges(ob,
-//                                       r,
-//                                       phi,  // 170 degrees
-//                                       0,    // z position of the input plane
-//                                       true,
-//                                       cfg.throw_on_cancel,
-//                                       ob, wh);
-
-//        pool.merge(curvedwalls);
-
-//        ExPolygon ob_contr = ob;
-//        ob_contr.holes.clear();
-
-//        auto pwalls = walls(ob_contr, inner_base, wh, -cfg.min_wall_height_mm,
-//                            cfg.throw_on_cancel);
-//        pool.merge(pwalls);
-
-//        Polygons top_triangles, bottom_triangles;
-//        triangulate(top_poly, top_triangles);
-//        triangulate(inner_base, bottom_triangles);
-//        auto top_plate = convert(top_triangles, 0, false);
-//        auto bottom_plate = convert(bottom_triangles, -HEIGHT, true);
-
-//        ob = inner_base; wh = 0;
-//        // rounded edge generation for the inner bed
-//        curvedwalls = round_edges(ob,
-//                                  cfg.edge_radius_mm,
-//                                  90,   // 90 degrees
-//                                  0,    // z position of the input plane
-//                                  false,
-//                                  cfg.throw_on_cancel,
-//                                  ob, wh);
-//        pool.merge(curvedwalls);
-
-//        auto innerbed = inner_bed(ob, cfg.min_wall_height_mm/2 + wh, wh);
-
-//        pool.merge(top_plate);
-//        pool.merge(bottom_plate);
-//        pool.merge(innerbed);
-
-//        out.merge(mesh(pool));
-//    }
 }
 
 }