My self-made 3D-printable designs, mainly in OpenSCAD
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rail-laser.scad 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. include <roundedcube.scad>
  2. $fn = 50;
  3. bodies_gap = 0.05;
  4. laser_dia = 6.5;
  5. laser_len = 14.0;
  6. bat_width = 18.0;
  7. bat_length = 30.0;
  8. bat_height = 9.0;
  9. bat_case_add = 1.0;
  10. switch_hole_dia = 2.2;
  11. switch_hole_dist = 15.0;
  12. switch_length = 19.6;
  13. switch_length_body = 10.6;
  14. switch_width = 5.7;
  15. switch_height = 12.0 + 2.0;
  16. switch_nub = 3.0;
  17. body_width = 25.0;
  18. body_length = 50.0;
  19. body_height = 42.0;
  20. body_frame_offset = 2.5;
  21. body_frame_gap = 0.5;
  22. body_cube_rounding = 1.0;
  23. body_bat_off = 5.5;
  24. body_switch_off_x = bat_height + 6.0;
  25. body_switch_off_y = 4.0;
  26. body_switch_add = 0.5;
  27. body_hole_dia_left = 2.5;
  28. body_hole_dia_right = 2.2;
  29. body_hole_off_x = 2.2;
  30. body_hole_off_z = body_hole_off_x;
  31. body_rail_lock_off_x = 10.0;
  32. body_rail_lock_off_z = 4.0;
  33. rail_width = 21.2;
  34. rail_height = 8.2;
  35. rail_lip_width_small = 1.3;
  36. rail_lip_width_big = 3.3;
  37. rail_lip_height = 1.0;
  38. rail_lock_width = 20.0;
  39. rail_lock_depth = 10.0;
  40. rail_lock_base_height = 3.0;
  41. rail_lock_pin_size = 5.0;
  42. rail_lock_pin_width = 10.0;
  43. rail_lock_pin_height = 5.0;
  44. rail_lock_tab_len = 1.0;
  45. rail_lock_tab_depth = 2.0;
  46. rail_lock_whole_width = body_width + (2 * rail_lock_tab_len);
  47. rail_lock_tab_width = (rail_lock_whole_width - rail_lock_width) / 2;
  48. rail_lock_travel = 5.0;
  49. rail_lock_spring_dia = 7.0;
  50. rail_lock_spring_hole = 1.0;
  51. frame_gap = 0.25;
  52. frame_sphere = 20;
  53. frame_add_touch = 4.0;
  54. frame_wall = 1.5;
  55. frame_mount_hole = 3.0;
  56. frame_mount_hole_off = 6.0;
  57. frame_mid_len = (frame_mount_hole / 4) + (2 * frame_wall);
  58. frame_mid_dia = laser_dia + (2 * frame_wall);
  59. frame_tail_len = 8.0;
  60. frame_tail_width = frame_mid_dia + 0.5;
  61. frame_negative_width = frame_sphere * 2 / 3 + 7;
  62. frame_hole_dia = 2.9;
  63. frame_hole_dia_arch = 3.3;
  64. frame_hole_off = 1.8;
  65. frame_hole_neg_off = 10;
  66. frame_hole_neg_len = 15;
  67. frame_hole_neg_deg_a = 9;
  68. frame_hole_neg_deg_b = frame_hole_neg_deg_a;
  69. frame_hole_neg_rad_small = frame_mid_len + ((frame_sphere + frame_tail_len) / 2) - frame_hole_off;
  70. frame_hole_neg_rad_large = frame_mid_len + ((frame_sphere + frame_tail_len) / 2) + frame_hole_off;
  71. frame_len = frame_sphere + frame_mid_len + frame_tail_len;
  72. //body_frame_off = body_height - rail_height - (frame_sphere / 2) - body_frame_offset;
  73. body_frame_off = (frame_sphere / 2) + body_frame_offset;
  74. module rail_lip(l) {
  75. hull() {
  76. translate([-1, -0.001, 0])
  77. cube([l + 2, 0.2, rail_lip_width_big]);
  78. translate([-1, rail_lip_height - 0.001, (rail_lip_width_big - rail_lip_width_small) / 2])
  79. cube([l + 2, 0.001, rail_lip_width_small]);
  80. }
  81. }
  82. module rail(l) {
  83. difference() {
  84. cube([l, rail_width, rail_height]);
  85. translate([0, 0, rail_height - rail_lip_width_big]) {
  86. rail_lip(l);
  87. translate([l, rail_width, 0])
  88. rotate([0, 0, 180])
  89. rail_lip(l);
  90. }
  91. }
  92. }
  93. module rail_lock_internal(add = 0.0) {
  94. if (add == 0) {
  95. cube([rail_lock_width + add, rail_lock_depth + add, rail_lock_base_height + add], center = true);
  96. translate([(rail_lock_width + add + rail_lock_tab_width + add) / 2, 0, 0])
  97. cube([rail_lock_tab_width + add, rail_lock_tab_depth + add, rail_lock_base_height + add], center = true);
  98. translate([-(rail_lock_width + add + rail_lock_tab_width + add) / 2, 0, 0])
  99. cube([rail_lock_tab_width + add, rail_lock_tab_depth + add, rail_lock_base_height + add], center = true);
  100. } else {
  101. translate([0, 0, -rail_lock_travel / 2]) {
  102. cube([rail_lock_width + add + 0.001, rail_lock_depth + add, rail_lock_base_height + add + rail_lock_travel + 0.001], center = true);
  103. translate([(rail_lock_width + add + rail_lock_tab_width + add) / 2, 0, 0])
  104. cube([rail_lock_tab_width + add, rail_lock_tab_depth + add, rail_lock_base_height + add + rail_lock_travel], center = true);
  105. translate([-(rail_lock_width + add + rail_lock_tab_width + add) / 2, 0, 0])
  106. cube([rail_lock_tab_width + add, rail_lock_tab_depth + add, rail_lock_base_height + add + rail_lock_travel], center = true);
  107. }
  108. }
  109. translate([0, 0, (rail_lock_base_height + add + rail_lock_pin_height + add) / 2])
  110. cube([rail_lock_pin_width + add, rail_lock_pin_size + add, rail_lock_pin_height + add], center = true);
  111. }
  112. module rail_lock(add = 0.0) {
  113. if (add == 0) {
  114. difference() {
  115. rail_lock_internal(add);
  116. translate([0, 0, -rail_lock_spring_hole - rail_lock_base_height / 2])
  117. cylinder(d = rail_lock_spring_dia, h = rail_lock_spring_hole + 1);
  118. translate([0, -rail_lock_pin_size / 2, (rail_lock_base_height + add + rail_lock_pin_height + add) / 2 - -rail_lock_pin_size / 2])
  119. rotate([45, 0, 0])
  120. cube([rail_lock_pin_width + 2, rail_lock_pin_size, rail_lock_pin_height], center = true);
  121. }
  122. } else {
  123. rail_lock_internal(add);
  124. translate([0, 0, -rail_lock_spring_hole - (rail_lock_base_height + add) / 2 - rail_lock_travel])
  125. cylinder(d = rail_lock_spring_dia, h = rail_lock_spring_hole);
  126. }
  127. }
  128. module laser() {
  129. cylinder(d = laser_dia, h = laser_len);
  130. }
  131. module laser_frame_screw_arc(radius, deg) {
  132. for (r = [-deg : 1 : deg])
  133. translate([radius, 0, 0])
  134. rotate([0, 0, r])
  135. translate([-radius, 0, 0])
  136. cylinder(d = frame_hole_dia_arch, h = frame_negative_width + frame_hole_neg_len);
  137. }
  138. module laser_frame(added_gap = 0, negative = 0) {
  139. difference() {
  140. union() {
  141. // top sphere
  142. translate([0, 0, (frame_sphere / 2) + (frame_len - frame_sphere)])
  143. sphere(d = frame_sphere + added_gap);
  144. if (negative == 0) {
  145. // mid section
  146. translate([0, 0, frame_len - frame_sphere - frame_mid_len - 0.5])
  147. cylinder(d = frame_mid_dia + added_gap, h = frame_mid_len + frame_add_touch + 1.0);
  148. // bottom cube
  149. translate([-(frame_tail_width + added_gap) / 2, -(frame_tail_width + added_gap) / 2, frame_len - frame_sphere - frame_mid_len - frame_tail_len]) {
  150. cube([frame_tail_width + added_gap, frame_tail_width + added_gap, frame_tail_len]);
  151. //roundedcube([frame_tail_width + added_gap, frame_tail_width + added_gap, frame_tail_len]);
  152. }
  153. } else {
  154. translate([0, 0, frame_len - frame_add_touch])
  155. cylinder(d = laser_dia + added_gap, h = frame_mid_len + frame_add_touch);
  156. translate([-frame_negative_width / 2, -frame_negative_width / 2, frame_len - frame_sphere - frame_mid_len - frame_tail_len - (added_gap * 3) - 1])
  157. cube([frame_negative_width, frame_negative_width, frame_len - frame_sphere + frame_add_touch + (added_gap * 3) + 1]);
  158. translate([-frame_hole_neg_off + frame_negative_width + frame_hole_neg_len, 0, frame_len - frame_sphere - frame_mid_len - frame_tail_len + (frame_tail_len / 2) - frame_hole_off])
  159. rotate([0, -90, 0])
  160. laser_frame_screw_arc(frame_hole_neg_rad_large, frame_hole_neg_deg_a);
  161. translate([0, -frame_hole_neg_off, frame_len - frame_sphere - frame_mid_len - frame_tail_len + (frame_tail_len / 2) + frame_hole_off])
  162. rotate([-90, -90, 0])
  163. laser_frame_screw_arc(frame_hole_neg_rad_small, frame_hole_neg_deg_b);
  164. }
  165. }
  166. if (negative == 0) {
  167. // cutout for laser itself
  168. translate([0, 0, -1])
  169. cylinder(d = laser_dia + (2 * frame_gap), h = frame_len + 2);
  170. // holding screws for laser
  171. translate([0, 0, frame_len - (frame_mount_hole / 2) - frame_mount_hole_off])
  172. rotate([0, 90, 45]) {
  173. cylinder(d = frame_mount_hole, h = frame_sphere);
  174. rotate([-90, 0, 0])
  175. cylinder(d = frame_mount_hole, h = frame_sphere);
  176. }
  177. // x-axis holes
  178. translate([-frame_tail_width / 2 - 1, 0, frame_len - frame_sphere - frame_mid_len - frame_tail_len + (frame_tail_len / 2) - frame_hole_off])
  179. rotate([0, 90, 0])
  180. cylinder(d = frame_hole_dia, h = frame_tail_width + 2);
  181. // y-axis holes
  182. translate([0, -frame_tail_width / 2 - 1, frame_len - frame_sphere - frame_mid_len - frame_tail_len + (frame_tail_len / 2) + frame_hole_off])
  183. rotate([-90, 0, 0])
  184. cylinder(d = frame_hole_dia, h = frame_tail_width + 2);
  185. }
  186. }
  187. }
  188. module battery(add = 0.0) {
  189. translate([-add / 2, -add / 2, -add / 2])
  190. cube([bat_height + add, bat_width + add, bat_length + add]);
  191. }
  192. module switch(add = 0.0) {
  193. translate([(switch_length - (switch_length_body + add * 2)) / 2, -add, 0])
  194. cube([(switch_length_body + add * 2), switch_width + add * 2, switch_height]);
  195. translate([(switch_length - switch_nub) / 2, (switch_width - switch_nub) / 2, switch_height])
  196. cube([switch_nub, switch_nub, switch_nub]);
  197. translate([(switch_length - switch_length_body) / 4, switch_width / 2, 0]) {
  198. cylinder(d = switch_hole_dia, h = switch_height + (switch_nub * 4));
  199. translate([switch_hole_dist, 0, 0])
  200. cylinder(d = switch_hole_dia, h = switch_height + (switch_nub * 4));
  201. }
  202. }
  203. module body(hole_dia) {
  204. difference() {
  205. // main body part
  206. cube([body_length, body_width, body_height]);
  207. //roundedcube([body_length, body_width, body_height], false, body_cube_rounding);
  208. // cutout for rail
  209. translate([-1, (body_width - rail_width) / 2, body_height - rail_height + 0.001])
  210. rail(body_length + 2);
  211. // cutout and preview for laser frame
  212. translate([body_length - frame_len, body_width / 2, body_frame_off])
  213. rotate([0, 90, 0]) {
  214. laser_frame(body_frame_gap, 1);
  215. %laser_frame();
  216. }
  217. // cutout and preview for battery
  218. translate([body_bat_off, (body_width - bat_width) / 2, (body_height - rail_height - bat_length) / 2]) {
  219. battery(bat_case_add);
  220. %battery();
  221. }
  222. // cutout and preview for switch
  223. translate([body_switch_off_x, body_width - switch_height + 0.001, body_height - rail_height - body_switch_off_y])
  224. rotate([-90, 0, 0]) {
  225. switch(body_switch_add);
  226. %switch(0);
  227. // cutout for cabling
  228. // TODO not very nice,
  229. // with hardcoded values
  230. translate([-0.001, -2.5, -8])
  231. cube([18.5, 30, 9.5]);
  232. }
  233. // cutout and preview for rail locking mechanism
  234. translate([body_length - body_rail_lock_off_x, body_width / 2, rail_lock_base_height / 2 + body_height - rail_height - body_rail_lock_off_z])
  235. rotate([0, 0, 90]) {
  236. rail_lock(0.5);
  237. %rail_lock();
  238. }
  239. // outside screw holes
  240. translate([body_hole_off_x, -1, body_hole_off_z])
  241. rotate([-90, 0, 0])
  242. cylinder(d = hole_dia, h = body_width + 2);
  243. translate([body_length - body_hole_off_x, -1, body_hole_off_z])
  244. rotate([-90, 0, 0])
  245. cylinder(d = hole_dia, h = body_width + 2);
  246. translate([body_hole_off_x, -1, body_height - rail_height - body_hole_off_z])
  247. rotate([-90, 0, 0])
  248. cylinder(d = hole_dia, h = body_width + 2);
  249. translate([body_length - body_hole_off_x, -1, body_height - rail_height - body_hole_off_z])
  250. rotate([-90, 0, 0])
  251. cylinder(d = hole_dia, h = body_width + 2);
  252. }
  253. }
  254. module body_half(half) {
  255. difference() {
  256. if (half == 0) {
  257. body(body_hole_dia_left);
  258. } else {
  259. body(body_hole_dia_right);
  260. }
  261. if (half == 0) {
  262. translate([-1, (bodies_gap - body_width) / 2, -1])
  263. cube([body_length + 2, body_width, body_height + 2]);
  264. } else {
  265. translate([-1, (body_width - bodies_gap) / 2, -1])
  266. cube([body_length + 2, body_width, body_height + 2]);
  267. }
  268. }
  269. }
  270. module print() {
  271. translate([0, 0, body_width])
  272. rotate([-90, 0, 0])
  273. body_half(0);
  274. translate([0, body_height * 2 + 5, 0])
  275. rotate([90, 0, 0])
  276. body_half(1);
  277. translate([body_length + 10, body_height + 2, 0])
  278. laser_frame(0, 0);
  279. translate([body_length + 10, 20, rail_lock_base_height / 2])
  280. rotate([0, 0, 90])
  281. rail_lock(0);
  282. // simple brim
  283. //translate([-10, -10, 0])
  284. //cube([80, 95, 0.2]);
  285. }
  286. //laser_frame();
  287. rail_lock();
  288. //body_half(0);
  289. //body_half(1);
  290. //print();