wireframe.scad
1 use <convex_offset.scad> 2 use <__comm__/_vertex_normals.scad> 3 use <util/reverse.scad> 4 5 module wireframe(points, faces, deep, outer_thickness, inner_thickness = 0, vertex_normals = undef) { 6 function hollow_face(pts, inner_pts) = 7 let( 8 leng = len(pts), 9 indices = [ 10 for(i = [0:leng - 1]) 11 let( 12 ni = (i + 1) % leng, 13 j = i + leng, 14 nj = ni + leng 15 ) 16 [i, ni, nj, j] 17 ] 18 ) 19 [concat(pts, inner_pts), indices]; 20 21 function hollow_faces(face_pts, offset_face_pts) = 22 let( 23 leng_face_pts = len(face_pts), 24 pts_faces = hollow_face( 25 face_pts[0], offset_face_pts[0] 26 ), 27 pts = pts_faces[0], 28 faces = pts_faces[1] 29 ) 30 _hollow_faces(face_pts, offset_face_pts, leng_face_pts, pts, faces); 31 32 function _hollow_faces(face_pts, offset_face_pts, leng_face_pts, pts, faces, i = 1) = 33 i == leng_face_pts ? [pts, faces] : 34 let( 35 pts_faces = hollow_face( 36 face_pts[i], offset_face_pts[i] 37 ), 38 npts = concat(pts, pts_faces[0]), 39 nfaces = concat(faces, [ 40 for(indice = pts_faces[1]) 41 [for(i = indice) i + len(pts)] 42 43 ]) 44 ) 45 _hollow_faces(face_pts, offset_face_pts, leng_face_pts, npts, nfaces, i + 1); 46 47 function side(pts, inner_pts) = 48 let( 49 leng_pts = len(pts), 50 indices = [ 51 for(i = [0:leng_pts - 1]) 52 let( 53 ni = (i + 1) % leng_pts, 54 j = i + leng_pts, 55 nj = ni + leng_pts 56 ) 57 [i, ni, nj, j] 58 ] 59 ) 60 [concat(pts, inner_pts), indices]; 61 62 function sides(pts1, pts2) = 63 let( 64 leng_pts = len(pts1), 65 pts_faces = side( 66 pts1[0], pts2[0] 67 ), 68 pts = pts_faces[0], 69 faces = pts_faces[1] 70 ) 71 _sides(pts1, pts2, leng_pts, pts, faces); 72 73 function _sides(pts1, pts2, leng_pts, pts, faces, i = 1) = 74 i == leng_pts ? [pts, faces] : 75 let( 76 pts_faces = side( 77 pts1[i], pts2[i] 78 ), 79 npts = concat(pts, pts_faces[0]), 80 nfaces = concat(faces, [ 81 for(indice = pts_faces[1]) 82 [for(i = indice) i + len(pts)] 83 84 ]) 85 ) 86 _sides(pts1, pts2, leng_pts, npts, nfaces, i + 1); 87 88 89 leng_faces = len(faces); 90 vx_normals = is_undef(vertex_normals) ? _vertex_normals(points, faces) : vertex_normals; 91 inner_pts = [ 92 for(i = [0:len(vx_normals) - 1]) 93 points[i] - vx_normals[i] * deep 94 ]; 95 96 face_pts = [ 97 for(i = [0:leng_faces - 1]) 98 [for(j = faces[i]) points[j]] 99 ]; 100 offset_face_pts = [ 101 for(face = faces) 102 convex_offset([for(i = face) points[i]], -outer_thickness) 103 ]; 104 105 face_inner_pts = [ 106 for(i = [0:leng_faces - 1]) 107 reverse([for(j = faces[i]) inner_pts[j]]) 108 ]; 109 offset_face_inner_pts = [ 110 for(face = faces) 111 inner_thickness == 0 ? [for(i = face) inner_pts[i]] : 112 reverse(convex_offset([for(i = face) inner_pts[i]], -inner_thickness)) 113 ]; 114 115 outer = hollow_faces(face_pts, offset_face_pts); 116 inner = inner_thickness == 0 ? [[], []] : hollow_faces(face_inner_pts, offset_face_inner_pts); 117 118 outer_inner_pts = concat(outer[0], inner[0]); 119 leng_outer = len(outer[0]); 120 outer_inner_faces = concat(outer[1], [ 121 for(face = inner[1]) 122 [for(i = face) leng_outer + i] 123 ]); 124 125 // offset_face_pts 126 offset_face_inner_pts2 = inner_thickness == 0 ? 127 offset_face_inner_pts : 128 [ 129 for(face_pts = offset_face_inner_pts) 130 reverse(face_pts) 131 ]; 132 133 hollow_sides = sides(offset_face_pts, offset_face_inner_pts2); 134 135 leng_outer_inner = len(outer_inner_pts); 136 137 all_points = concat(outer_inner_pts, hollow_sides[0]); 138 all_faces = concat(outer_inner_faces, [ 139 for(face = hollow_sides[1]) 140 [for(i = face) leng_outer_inner + i] 141 ]); 142 143 if(deep > 0) { 144 polyhedron(all_points, all_faces); 145 } 146 else { 147 polyhedron(all_points, [for(f = all_faces) reverse(f)]); 148 } 149 } 150 151 /* 152 deep = 0.2; 153 thickness = 0.2; 154 155 points = [[-1, -1, 0], [-1, 1, 0], [0, 0, -1], [0, 0, 1], [1, -1, 0], [1, 1, 0], [1, 1, 1]]; 156 157 faces = [[2, 1, 0], [3, 0, 1], [4, 2, 0], [4, 0, 3], [5, 1, 2], [5, 2, 4], [6, 3, 1], [6, 1, 5], [6, 4, 3], [6, 5, 4]]; 158 159 wireframe(points, faces, deep, thickness); 160 161 cubePoints = [ 162 [ 0, 0, 0], //0 163 [ 2, 0, 0], //1 164 [ 2, 1.4, 0], //2 165 [ 0, 1.4, 0], //3 166 [ 0, 0, 1], //4 167 [ 2, 0, 1], //5 168 [ 2, 1.4, 1], //6 169 [ 0, 1.4, 1]]; //7 170 171 cubeFaces = [ 172 [0,1,2,3], // bottom 173 [4,5,1,0], // front 174 [7,6,5,4], // top 175 [5,6,2,1], // right 176 [6,7,3,2], // back 177 [7,4,0,3]]; // left 178 179 translate([2, 0, 0]) 180 wireframe( cubePoints, cubeFaces, deep, thickness);*/