shelf.scad 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. include <../config/shelf.scad>
  2. include <../config/wall.scad>
  3. include <thread.scad>
  4. function shelf_mounting_width() = shelf_angle_depth - shelf_rounding * 2;
  5. function shelf_mounting_holes() = [
  6. shelf_mounting_width() / 4,
  7. shelf_mounting_width() / 4 * 3
  8. ];
  9. module shelf_angle_object() {
  10. module base_shape() {
  11. move_x = shelf_angle_depth / 2 - shelf_rounding;
  12. move_y = shelf_angle_height / 2 - shelf_rounding;
  13. module base() {
  14. hull() {
  15. translate([-move_x, move_y]) {
  16. circle(r = shelf_rounding);
  17. }
  18. translate([-move_x, -move_y]) {
  19. circle(r = shelf_rounding);
  20. }
  21. }
  22. hull() {
  23. translate([-move_x, shelf_rounding]) {
  24. square(shelf_rounding * 2, center = true);
  25. }
  26. translate([move_x, shelf_rounding]) {
  27. circle(r = shelf_rounding);
  28. }
  29. translate([-move_x, -shelf_rounding]) {
  30. square(shelf_rounding * 2, center = true);
  31. }
  32. translate([move_x, -shelf_rounding]) {
  33. circle(r = shelf_rounding);
  34. }
  35. }
  36. }
  37. module reverse_corner(size = 10, rotation = 0) {
  38. module base() {
  39. difference() {
  40. square(size * 2, center = true);
  41. circle(r = size);
  42. }
  43. }
  44. module mask() {
  45. translate([0, size / 2]) {
  46. square([size * 2, size], center = true);
  47. }
  48. translate([size / 2, -size / 2]) {
  49. square(size, center = true);
  50. }
  51. }
  52. render() {
  53. rotate(90 * rotation) {
  54. translate([size / 2, size / 2]) {
  55. difference() {
  56. base();
  57. mask();
  58. }
  59. }
  60. }
  61. }
  62. }
  63. module indentation() {
  64. width = shelf_angle_depth - shelf_rounding * 2;
  65. height = shelf_thickness;
  66. translate([shelf_rounding, 0]) {
  67. square([width, height], center = true);
  68. }
  69. }
  70. render() {
  71. difference() {
  72. base();
  73. indentation();
  74. }
  75. }
  76. test_height = shelf_angle_height / 2 - shelf_rounding * 3;
  77. test_depth = shelf_angle_depth - shelf_rounding * 3;
  78. size = min(test_height, test_depth);
  79. corner_move_x = size / 2 - shelf_angle_depth / 2 + shelf_rounding * 2;
  80. corner_move_y = size / 2 + shelf_rounding * 2;
  81. translate([corner_move_x, corner_move_y]) {
  82. reverse_corner(size, 0);
  83. }
  84. translate([corner_move_x, -corner_move_y]) {
  85. reverse_corner(size, 3);
  86. }
  87. }
  88. module base_object() {
  89. linear_extrude(height = shelf_angle_thickness, center = true) {
  90. base_shape();
  91. }
  92. }
  93. module wall_thread(move_y = 0, split) {
  94. move_x = (split ? 0 : shelf_rounding * 2)
  95. - shelf_angle_depth / 2
  96. - thread_height / 2 * (split ? -1 : 1);
  97. render() {
  98. translate([move_x, move_y, 0]) {
  99. rotate([0, split ? 90 : 270, 0]) {
  100. thread_object();
  101. translate([0, 0, -thread_height / 2]) {
  102. rotate([0, 180, 0]) {
  103. radius = thread_top_diameter / 2;
  104. height = shelf_angle_depth;
  105. cylinder(r = radius, h = height);
  106. }
  107. }
  108. }
  109. }
  110. translate([0, move_y, 0]) {
  111. rotate([0, 90, 0]) {
  112. thread_screw_object(shelf_angle_depth * 2);
  113. }
  114. }
  115. }
  116. }
  117. module mount_thread(move_x) {
  118. move_y = shelf_thickness / 2 + thread_height / 2 + 1;
  119. translate([move_x, move_y, 0]) {
  120. rotate([90, 0, 0]) {
  121. render() {
  122. thread_object();
  123. thread_screw_object(shelf_angle_height * 2);
  124. rotate([0, 180, 0]) {
  125. radius = thread_top_diameter / 2;
  126. height = shelf_angle_height;
  127. translate([0, 0, thread_height / 2]) {
  128. cylinder(r = radius, h = height);
  129. }
  130. }
  131. screw_height = thread_height / 2
  132. + shelf_thickness
  133. + shelf_rounding;
  134. translate([0, 0, screw_height]) {
  135. cylinder(r = thread_screw, h = shelf_angle_height);
  136. }
  137. }
  138. }
  139. }
  140. }
  141. module final_object() {
  142. render() {
  143. difference() {
  144. base_object();
  145. correction = shelf_angle_height % wall_holes_space;
  146. move = (shelf_angle_height - correction) / 2;
  147. for (count = [-move : wall_holes_space : move]) {
  148. wall_thread(count, count == 0);
  149. }
  150. for (count = shelf_mounting_holes()) {
  151. correction = shelf_rounding * 2 - shelf_angle_depth / 2;
  152. mount_thread(count + correction);
  153. }
  154. }
  155. }
  156. }
  157. color("#005555") {
  158. render() {
  159. final_object();
  160. }
  161. }
  162. }
  163. module shelf_shape() {
  164. module base_shape() {
  165. move_x = shelf_width / 2 - shelf_rounding;
  166. move_y = shelf_depth / 2 - shelf_rounding;
  167. module corner(move) {
  168. translate(move) {
  169. circle(r = shelf_rounding);
  170. }
  171. }
  172. render() {
  173. hull() {
  174. corner([move_x, move_y]);
  175. corner([-move_x, move_y]);
  176. corner([move_x, -move_y]);
  177. corner([-move_x, -move_y]);
  178. }
  179. }
  180. }
  181. module mounting_holes() {
  182. base_move = shelf_width - shelf_width % wall_holes_space;
  183. move = base_move / 2;
  184. indentation_y = shelf_depth / 2;
  185. for (count_x = [-move : wall_holes_space : move]) {
  186. translate([count_x, -indentation_y]) {
  187. size = [shelf_angle_thickness, shelf_rounding * 4];
  188. square(size, center = true);
  189. }
  190. for (count_y = shelf_mounting_holes()) {
  191. holes_y = count_y
  192. - shelf_depth / 2
  193. + shelf_rounding * 2;
  194. translate([count_x, holes_y]) {
  195. circle(r = thread_screw / 2);
  196. }
  197. }
  198. }
  199. }
  200. module inside_holes() {
  201. move_x = (shelf_width - shelf_width % shelf_inside_holes_space) / 2;
  202. move_y = (shelf_depth - shelf_depth % shelf_inside_holes_space) / 2;
  203. for (count_x = [-move_x : shelf_inside_holes_space : move_x]) {
  204. for (count_y = [-move_y : shelf_inside_holes_space : move_y]) {
  205. translate([count_x, count_y]) {
  206. circle(r = shelf_inside_hole / 2);
  207. }
  208. }
  209. }
  210. }
  211. module vesa_holes() {
  212. translate(shelf_vesa_holes_move) {
  213. move_x = shelf_vesa_holes_width / 2;
  214. move_y = shelf_vesa_holes_depth / 2;
  215. translate([move_x, move_y]) {
  216. circle(r = shelf_vesa_hole / 2);
  217. }
  218. translate([-move_x, move_y]) {
  219. circle(r = shelf_vesa_hole / 2);
  220. }
  221. translate([move_x, -move_y]) {
  222. circle(r = shelf_vesa_hole / 2);
  223. }
  224. translate([-move_x, -move_y]) {
  225. circle(r = shelf_vesa_hole / 2);
  226. }
  227. }
  228. }
  229. module final_shape() {
  230. difference() {
  231. base_shape();
  232. mounting_holes();
  233. if (shelf_vesa_holes_enable) {
  234. vesa_holes();
  235. }
  236. if (shelf_inside_holes_enable) {
  237. inside_holes();
  238. }
  239. }
  240. }
  241. render() {
  242. final_shape();
  243. }
  244. }
  245. module shelf_object() {
  246. module base() {
  247. linear_extrude(height = shelf_thickness, center = true) {
  248. shelf_shape();
  249. }
  250. }
  251. color("#AAAAAA") {
  252. render() {
  253. base();
  254. }
  255. }
  256. }