/ src / surface / sf_thickenT.scad
sf_thickenT.scad
 1  /**
 2  * sf_thickenT.scad
 3  *
 4  * @copyright Justin Lin, 2021
 5  * @license https://opensource.org/licenses/lgpl-3.0.html
 6  *
 7  * @see https://openhome.cc/eGossip/OpenSCAD/lib3x-sf_thickenT.html
 8  *
 9  **/ 
10  
11  use <../__comm__/__to2d.scad>
12  use <../__comm__/_face_normal.scad>
13  use <../util/sorted.scad>
14  use <../util/sum.scad>
15  use <../util/contains.scad>
16  use <../util/unit_vector.scad>
17  use <../surface/sf_solidifyT.scad>
18  use <../triangle/tri_delaunay.scad>
19  
20  module sf_thickenT(points, thickness, triangles = undef, direction = "BOTH", convexity = 1) {
21      // triangles : counter-clockwise
22      real_triangles = is_undef(triangles) ? tri_delaunay([for(p = points) __to2d(p)]) : triangles;
23  
24      leng_pts = len(points);
25      conn_indices_tris = [for(tri = real_triangles, i = tri) [i, tri]];
26  
27      if(is_list(direction)) {
28          dir_v = unit_vector(direction);
29  
30          mid_pt = sorted(points)[leng_pts / 2];
31          mid_i = search([mid_pt], points)[0];
32          indices = search(mid_i, conn_indices_tris, num_returns_per_match = 0);
33          nvs = [
34              for(j = indices) 
35              let(tri = conn_indices_tris[j][1])
36              _face_normal([for(i = [2, 1, 0]) points[tri[i]]]) // OpenSCAD requires clockwise
37          ]; 
38          nv = sum(nvs) / len(nvs);   
39          
40          off = dir_v * thickness;
41          pts = [for(p = points) p + off];
42  
43          if(nv * dir_v > 0) {
44              sf_solidifyT(pts, points, real_triangles, convexity = convexity);
45          }
46          else {
47              sf_solidifyT(points, pts, real_triangles, convexity = convexity);
48          }
49      }
50      else {
51          vertex_normals = [
52              for(i = [0:leng_pts - 1])
53              let(
54                  indices = search(i, conn_indices_tris, num_returns_per_match = 0),
55                  face_normals = [ 
56                      for(j = indices)
57                      let(tri = conn_indices_tris[j][1])
58                      _face_normal([for(k = [2, 1, 0]) points[tri[k]]]) // OpenSCAD requires clockwise
59                  ]
60              )
61              sum(face_normals) / len(face_normals)
62          ];
63  
64          if(direction == "BOTH") {
65              off = vertex_normals * (thickness / 2);
66              sf_solidifyT(points + off, points - off, real_triangles, convexity = convexity);
67          }
68          else if(direction == "FORWARD") {
69              sf_solidifyT(points + vertex_normals * thickness, points, real_triangles, convexity = convexity);
70          }
71          else {
72              sf_solidifyT(points, points - vertex_normals * thickness, real_triangles, convexity = convexity);
73          }
74      }
75  }