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 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. include <roundedcube.scad>
  2. $fn = 50;
  3. bodies_gap = 0.05;
  4. laser_dia = 6.5 + 0.2;
  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.2;
  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.23 - 0.1;
  42. rail_lock_pin_width = 12.0;
  43. rail_lock_pin_height = 5.0;
  44. rail_lock_tab_len = 0.5;
  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 = 3.0;
  54. frame_wall = 1.5;
  55. frame_mount_hole = 2.85;
  56. frame_mount_hole_off_1 = 3.0;
  57. frame_mount_hole_off_2 = 8.0;
  58. frame_mid_len = (frame_mount_hole / 4) + (2 * frame_wall);
  59. frame_mid_dia = 8; //laser_dia + (2 * frame_wall);
  60. frame_tail_len = 8.0;
  61. frame_tail_len_add = 1.0;
  62. frame_tail_width = 5.5; //frame_mid_dia + 0.5;
  63. frame_negative_width = frame_sphere * 2 / 3 + 7;
  64. frame_hole_dia = 2.85;
  65. frame_hole_dia_arch = 3.0 + 0.1;
  66. frame_hole_off = 1.8;
  67. frame_hole_neg_off = 10;
  68. frame_hole_neg_len = 15;
  69. frame_hole_neg_deg_a = 9;
  70. frame_hole_neg_deg_b = frame_hole_neg_deg_a;
  71. frame_brim_height = 0.5;
  72. frame_brim_width = 20.0;
  73. frame_hole_neg_rad_small = frame_mid_len + ((frame_sphere + frame_tail_len) / 2) - frame_hole_off;
  74. frame_hole_neg_rad_large = frame_mid_len + ((frame_sphere + frame_tail_len) / 2) + frame_hole_off;
  75. frame_len = frame_sphere + frame_mid_len + frame_tail_len;
  76. //body_frame_off = body_height - rail_height - (frame_sphere / 2) - body_frame_offset;
  77. body_frame_off = (frame_sphere / 2) + body_frame_offset;
  78. laser_preview_angle_x = -10 + (20 * $t);
  79. laser_preview_angle_y = -10 + (20 * $t);
  80. module rail_lip(l) {
  81. hull() {
  82. translate([-1, -0.01, 0])
  83. cube([l + 2, 0.2, rail_lip_width_big]);
  84. translate([-1, rail_lip_height - 0.01, (rail_lip_width_big - rail_lip_width_small) / 2])
  85. cube([l + 2, 0.01, rail_lip_width_small]);
  86. }
  87. }
  88. module rail(l) {
  89. difference() {
  90. cube([l, rail_width, rail_height]);
  91. translate([0, 0, rail_height - rail_lip_width_big]) {
  92. rail_lip(l);
  93. translate([l, rail_width, 0])
  94. rotate([0, 0, 180])
  95. rail_lip(l);
  96. }
  97. }
  98. }
  99. module rail_lock_internal(add = 0.0) {
  100. if (add == 0) {
  101. cube([rail_lock_width + add, rail_lock_depth + add, rail_lock_base_height + add], center = true);
  102. translate([(rail_lock_width + add + rail_lock_tab_width + add) / 2, 0, 0])
  103. cube([rail_lock_tab_width + add, rail_lock_tab_depth + add, rail_lock_base_height + add], center = true);
  104. translate([-(rail_lock_width + add + rail_lock_tab_width + add) / 2, 0, 0])
  105. cube([rail_lock_tab_width + add, rail_lock_tab_depth + add, rail_lock_base_height + add], center = true);
  106. } else {
  107. translate([0, 0, -rail_lock_travel / 2]) {
  108. cube([rail_lock_width + add + 0.01, rail_lock_depth + add, rail_lock_base_height + add + rail_lock_travel + 0.01], center = true);
  109. translate([(rail_lock_width + add + rail_lock_tab_width + add) / 2, 0, 0])
  110. cube([rail_lock_tab_width + add, rail_lock_tab_depth + add, rail_lock_base_height + add + rail_lock_travel], center = true);
  111. translate([-(rail_lock_width + add + rail_lock_tab_width + add) / 2, 0, 0])
  112. cube([rail_lock_tab_width + add, rail_lock_tab_depth + add, rail_lock_base_height + add + rail_lock_travel], center = true);
  113. }
  114. }
  115. translate([0, 0, (rail_lock_base_height + add + rail_lock_pin_height + add) / 2])
  116. cube([rail_lock_pin_width + add, rail_lock_pin_size + add, rail_lock_pin_height + add], center = true);
  117. }
  118. module rail_lock(add = 0.0) {
  119. if (add == 0) {
  120. difference() {
  121. rail_lock_internal(add);
  122. translate([0, 0, -rail_lock_spring_hole - rail_lock_base_height / 2])
  123. cylinder(d = rail_lock_spring_dia, h = rail_lock_spring_hole + 1);
  124. translate([0, -rail_lock_pin_size / 2, (rail_lock_base_height + add + rail_lock_pin_height + add) / 2 - -rail_lock_pin_size / 2])
  125. rotate([45, 0, 0])
  126. cube([rail_lock_pin_width + 2, rail_lock_pin_size, rail_lock_pin_height], center = true);
  127. }
  128. } else {
  129. rail_lock_internal(add);
  130. translate([0, 0, -rail_lock_spring_hole - (rail_lock_base_height + add) / 2 - rail_lock_travel])
  131. cylinder(d = rail_lock_spring_dia, h = rail_lock_spring_hole);
  132. }
  133. }
  134. module laser() {
  135. cylinder(d = laser_dia, h = laser_len);
  136. }
  137. module laser_frame_screw_arc(radius, deg) {
  138. for (r = [-deg : 1 : deg])
  139. translate([radius, 0, 0])
  140. rotate([0, 0, r])
  141. translate([-radius, 0, 0])
  142. cylinder(d = frame_hole_dia_arch, h = frame_negative_width + frame_hole_neg_len);
  143. }
  144. module laser_frame(added_gap = 0, negative = 0) {
  145. difference() {
  146. union() {
  147. // top sphere
  148. translate([0, 0, (frame_sphere / 2) + (frame_len - frame_sphere)])
  149. sphere(d = frame_sphere + added_gap);
  150. if (negative == 0) {
  151. %translate([0, 0, frame_len - frame_sphere / 2])
  152. cylinder(d = 0.5, h = 50);
  153. // mid section
  154. translate([0, 0, frame_len - frame_sphere - frame_mid_len - 0.5])
  155. hull() {
  156. translate([-(frame_tail_width + added_gap) / 2, -(frame_tail_width + added_gap) / 2, 0])
  157. cube([frame_tail_width + added_gap, frame_tail_width + added_gap, frame_tail_len]);
  158. translate([0, 0, frame_mid_len + frame_add_touch])
  159. cylinder(d = frame_mid_dia + added_gap, h = 1.0);
  160. }
  161. // bottom cube
  162. translate([-(frame_tail_width + added_gap) / 2, -(frame_tail_width + added_gap) / 2, frame_len - frame_sphere - frame_mid_len - frame_tail_len - frame_tail_len_add]) {
  163. cube([frame_tail_width + added_gap, frame_tail_width + added_gap, frame_tail_len + frame_tail_len_add]);
  164. //roundedcube([frame_tail_width + added_gap, frame_tail_width + added_gap, frame_tail_len]);
  165. }
  166. } else {
  167. translate([0, 0, frame_len - frame_add_touch])
  168. cylinder(d = laser_dia + added_gap, h = frame_mid_len + frame_add_touch);
  169. translate([-frame_negative_width / 2, -frame_negative_width / 2, frame_len - frame_sphere - frame_mid_len - frame_tail_len - (added_gap * 3) - 1])
  170. cube([frame_negative_width, frame_negative_width, frame_len - frame_sphere + frame_add_touch + (added_gap * 3) + 1]);
  171. 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])
  172. rotate([0, -90, 0])
  173. laser_frame_screw_arc(frame_hole_neg_rad_large, frame_hole_neg_deg_a);
  174. translate([0, -frame_hole_neg_off, frame_len - frame_sphere - frame_mid_len - frame_tail_len + (frame_tail_len / 2) + frame_hole_off])
  175. rotate([-90, -90, 0])
  176. laser_frame_screw_arc(frame_hole_neg_rad_small, frame_hole_neg_deg_b);
  177. }
  178. }
  179. if (negative == 0) {
  180. // cutout for laser itself
  181. translate([0, 0, frame_len - frame_sphere + 1])
  182. cylinder(d = laser_dia + (2 * frame_gap), h = frame_sphere);
  183. // holding screws for laser
  184. translate([0, 0, frame_len - (frame_mount_hole / 2) - frame_mount_hole_off_1])
  185. rotate([0, 90, 45]) {
  186. cylinder(d = frame_mount_hole, h = frame_sphere);
  187. rotate([-90, 0, 0])
  188. cylinder(d = frame_mount_hole, h = frame_sphere);
  189. }
  190. translate([0, 0, frame_len - (frame_mount_hole / 2) - frame_mount_hole_off_2])
  191. rotate([0, 90, 45]) {
  192. cylinder(d = frame_mount_hole, h = frame_sphere);
  193. rotate([-90, 0, 0])
  194. cylinder(d = frame_mount_hole, h = frame_sphere);
  195. }
  196. // cable cutout for laser
  197. //rotate([0, 0, -90])
  198. translate([0, 5, 6.5])
  199. rotate([30, 0, 0])
  200. cylinder(d = 2.5, h = 10);
  201. // x-axis holes
  202. translate([-frame_tail_width / 2 - 1, 0, frame_len - frame_sphere - frame_mid_len - frame_tail_len + (frame_tail_len / 2) - frame_hole_off])
  203. rotate([0, 90, 0])
  204. cylinder(d = frame_hole_dia, h = frame_tail_width + 2);
  205. // y-axis holes
  206. translate([0, -frame_tail_width / 2 - 1, frame_len - frame_sphere - frame_mid_len - frame_tail_len + (frame_tail_len / 2) + frame_hole_off])
  207. rotate([-90, 0, 0])
  208. cylinder(d = frame_hole_dia, h = frame_tail_width + 2);
  209. }
  210. }
  211. }
  212. module battery(add = 0.0) {
  213. translate([-add / 2, -add / 2, -add / 2])
  214. cube([bat_height + add, bat_width + add, bat_length + add]);
  215. }
  216. module switch(add = 0.0) {
  217. translate([(switch_length - (switch_length_body + add * 2)) / 2, -add, 0])
  218. cube([(switch_length_body + add * 2), switch_width + add * 2, switch_height]);
  219. translate([(switch_length - switch_nub) / 2, (switch_width - switch_nub) / 2, switch_height])
  220. cube([switch_nub, switch_nub, switch_nub]);
  221. translate([(switch_length - switch_length_body) / 4, switch_width / 2, 0]) {
  222. cylinder(d = switch_hole_dia, h = switch_height + 1);
  223. translate([switch_hole_dist, 0, 0])
  224. cylinder(d = switch_hole_dia, h = switch_height + 1);
  225. }
  226. }
  227. module body(hole_dia) {
  228. difference() {
  229. // main body part
  230. cube([body_length, body_width, body_height]);
  231. //roundedcube([body_length, body_width, body_height], false, body_cube_rounding);
  232. // cutout for rail
  233. translate([-1, (body_width - rail_width) / 2, body_height - rail_height + 0.01])
  234. rail(body_length + 2);
  235. // cutout and preview for laser frame
  236. translate([body_length - frame_len, body_width / 2, body_frame_off])
  237. rotate([0, 90, 0]) {
  238. laser_frame(body_frame_gap, 1);
  239. translate([0, 0, frame_len - frame_sphere / 2])
  240. rotate([laser_preview_angle_x, laser_preview_angle_y, 180])
  241. translate([0, 0, -(frame_len - frame_sphere / 2)])
  242. %laser_frame();
  243. }
  244. // cutout and preview for battery
  245. translate([body_bat_off, (body_width - bat_width) / 2, (body_height - rail_height - bat_length) / 2]) {
  246. battery(bat_case_add);
  247. %battery();
  248. }
  249. // cutout and preview for switch
  250. translate([body_switch_off_x, body_width - switch_height + 0.01, body_height - rail_height - body_switch_off_y])
  251. rotate([-90, 0, 0]) {
  252. switch(body_switch_add);
  253. %switch(0);
  254. // cutout for cabling
  255. // TODO not very nice,
  256. // with hardcoded values
  257. translate([-0.01, -2.5, -8])
  258. cube([18.5, 30, 9.5]);
  259. }
  260. // cutout and preview for rail locking mechanism
  261. 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])
  262. rotate([0, 0, -90]) {
  263. rail_lock(0.5);
  264. translate([0, 0, -(rail_lock_travel * $t)])
  265. %rail_lock();
  266. }
  267. // outside screw holes
  268. translate([body_hole_off_x, -1, body_hole_off_z])
  269. rotate([-90, 0, 0])
  270. cylinder(d = hole_dia, h = body_width + 2);
  271. translate([body_length - body_hole_off_x, -1, body_hole_off_z])
  272. rotate([-90, 0, 0])
  273. cylinder(d = hole_dia, h = body_width + 2);
  274. translate([body_hole_off_x, -1, body_height - rail_height - body_hole_off_z])
  275. rotate([-90, 0, 0])
  276. cylinder(d = hole_dia, h = body_width + 2);
  277. translate([body_length - body_hole_off_x, -1, body_height - rail_height - body_hole_off_z])
  278. rotate([-90, 0, 0])
  279. cylinder(d = hole_dia, h = body_width + 2);
  280. }
  281. }
  282. module body_half(half) {
  283. difference() {
  284. if (half == 0) {
  285. body(body_hole_dia_left);
  286. } else {
  287. body(body_hole_dia_right);
  288. }
  289. if (half == 0) {
  290. translate([-1, (bodies_gap - body_width) / 2, -1])
  291. cube([body_length + 2, body_width, body_height + 2]);
  292. } else {
  293. translate([-1, (body_width - bodies_gap) / 2, -1])
  294. cube([body_length + 2, body_width, body_height + 2]);
  295. }
  296. }
  297. }
  298. module print() {
  299. translate([0, 0, body_width])
  300. rotate([-90, 0, 0])
  301. body_half(0);
  302. translate([0, body_height * 2 + 5, 0])
  303. rotate([90, 0, 0])
  304. body_half(1);
  305. translate([body_length + (frame_brim_width / 2) + 5, body_height + (frame_brim_width / 2) + 5, 0]) {
  306. translate([0, 0, frame_tail_len_add])
  307. laser_frame(0, 0);
  308. translate([0, 0, frame_brim_height / 2])
  309. cube([frame_brim_width, frame_brim_width, frame_brim_height], center = true);
  310. }
  311. translate([body_length + 10, 20, rail_lock_base_height / 2])
  312. rotate([0, 0, 90])
  313. rail_lock(0);
  314. // simple brim
  315. //translate([-10, -10, 0])
  316. //cube([80, 95, 0.2]);
  317. }
  318. //laser_frame();
  319. //rail_lock();
  320. //body_half(0);
  321. //body_half(1);
  322. print();