PluggableContainer.scad 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. // -> increase the number for smoother edges
  2. $fn=30;
  3. // -> the length of the box
  4. totalLen=45.0;
  5. // -> the width of the box
  6. totalWid=20.0;
  7. // -> the total height of the box
  8. totalHei=100.0;
  9. // -> the radius of the side part
  10. sideRad=4.0;
  11. // -> the height of the roundings on top
  12. topRad=5.0;
  13. // -> the radius of fillets and outer roundings
  14. filletRad=2.0;
  15. // -> wall thickness
  16. wallThic=1.6;
  17. // -> the height of the lid
  18. lidHei=15.0;
  19. // -> the height of the overlapping part in the lid
  20. lidOve=5.0;
  21. // -> small amount that makes lid bigger than body in order to get a better fit between them on not so exact printers.
  22. clearence=0.1;
  23. ////////////////////////////////////////////////////////////////////
  24. // used for a very very very thin wall that will be extruded.
  25. minThic=0.05;
  26. // size that is used for the object that cuts the containers in a plane
  27. cutSize=max(totalLen,totalHei,totalWid);
  28. echo("-> main():");
  29. echo(" totalLen: ", totalLen);
  30. echo(" totalWid: ", totalWid);
  31. echo(" totalHei: ", totalHei);
  32. echo(" sideRad: ", sideRad);
  33. echo(" topRad: ", topRad);
  34. echo(" filletRad: ", filletRad);
  35. echo(" wallThic: ", wallThic);
  36. echo(" lidHei: ", lidHei);
  37. echo(" lidOve: ", lidOve);
  38. echo(" clearence: ", clearence);
  39. echo(" minThic: ", minThic);
  40. echo(" cutSize: ", cutSize);
  41. ////////////////////////////////////////////////////////////////////
  42. // main
  43. ////////////////////////////////////////////////////////////////////
  44. translate([-9.5*totalWid,0,0])
  45. pluggableContainer()
  46. polygon([[-totalWid,totalWid],[totalWid,totalWid],[0,-totalWid]]);
  47. translate([-7*totalWid,0,0])
  48. pluggableContainer()
  49. circle(r=totalWid, $fn=5);
  50. translate([-4.5*totalWid,0,0])
  51. pluggableContainer()
  52. circle(r=totalWid, $fn=6);
  53. translate([-2*totalWid,0,0])
  54. pluggableContainer()
  55. circle(r=totalWid, $fn=8);
  56. translate([totalWid/2,0,0])
  57. pluggableContainer()
  58. circle(r=totalWid);
  59. translate([3*totalWid,0,0])
  60. pluggableContainer()
  61. square([totalLen, totalWid], center=true);
  62. translate([6*totalWid,0,0])
  63. pluggableContainer()
  64. makeBase00(totalLen, totalWid, sideRad);
  65. translate([9*totalWid,0,0])
  66. pluggableContainer00();
  67. translate([12*totalWid,0,0])
  68. pluggableContainer01();
  69. translate([15*totalWid,0,0])
  70. pluggableContainer()
  71. scale([totalLen, totalWid])
  72. circle(d=1);
  73. translate([18*totalWid,0,0])
  74. pluggableContainer02();
  75. ////////////////////////////////////////////////////////////////////
  76. // modules
  77. ////////////////////////////////////////////////////////////////////
  78. ////////////////////////////////////////////////////////////////////
  79. module pluggableContainer()
  80. {
  81. makeBody(totalHei, filletRad, wallThic, lidHei, lidOve)
  82. children(0);
  83. translate([0,-2*totalWid,0])
  84. makeLid(totalHei, filletRad, wallThic, lidHei, lidOve)
  85. children(0);
  86. }
  87. ////////////////////////////////////////////////////////////////////
  88. module makeBody(height, fillet, wall, lid, overlap)
  89. {
  90. union()
  91. {
  92. cutTop(height-lid)
  93. makeOuterBody(fillet, wall)
  94. children(0);
  95. // inner body
  96. cutTop(height-lid+overlap)
  97. makeInnerBody(fillet, wall)
  98. children(0);
  99. }
  100. }
  101. ////////////////////////////////////////////////////////////////////
  102. module makeLid(height, fillet, wall, lid, overlap)
  103. {
  104. union()
  105. {
  106. cutTop(lid)
  107. makeOuterBody(fillet, wall)
  108. offset(clearence)
  109. children(0);
  110. // inner body
  111. cutTop(lid-overlap)
  112. makeInnerBody(fillet, wall)
  113. offset(clearence)
  114. children(0);
  115. }
  116. }
  117. ////////////////////////////////////////////////////////////////////
  118. module makeOuterBody(fillet, wall)
  119. {
  120. difference()
  121. {
  122. roundedBox(fillet)
  123. children(0);
  124. translate([0,0,wall/2])
  125. roundedBox(fillet)
  126. offset(-wall/2)
  127. children(0);
  128. }
  129. }
  130. ////////////////////////////////////////////////////////////////////
  131. module makeInnerBody(fillet, wall)
  132. {
  133. translate([0,0,wall/2])
  134. difference()
  135. {
  136. roundedBox(fillet)
  137. offset(-wall/2)
  138. children(0);
  139. translate([0,0,wall/2])
  140. roundedBox(fillet)
  141. offset(-wall)
  142. children(0);
  143. }
  144. }
  145. //////////////////////////////////////////////////////////////////////
  146. module roundedBox(filletRadius)
  147. {
  148. hull()
  149. {
  150. translate([0,0,totalHei-filletRad])
  151. makeTop(filletRadius)
  152. offset(-filletRad)
  153. children(0);
  154. translate([0,0,filletRad])
  155. makeBottom(filletRadius)
  156. offset(-filletRad)
  157. children(0);
  158. }
  159. }
  160. ////////////////////////////////////////////////////////////////////
  161. module makeTop(filletRadius)
  162. {
  163. cutBottom(0)
  164. makeFillet(filletRadius)
  165. children(0);
  166. }
  167. ////////////////////////////////////////////////////////////////////
  168. module makeBottom(filletRadius)
  169. {
  170. cutTop(0)
  171. makeFillet(filletRadius)
  172. children(0);
  173. }
  174. ////////////////////////////////////////////////////////////////////
  175. module makeFillet(filletRadius)
  176. {
  177. minkowski()
  178. {
  179. sphere(r=filletRadius);
  180. translate([0,0,-minThic/2])
  181. linear_extrude(minThic, convexity=8)
  182. children(0);
  183. }
  184. }
  185. ////////////////////////////////////////////////////////////////////
  186. ////////////////////////////////////////////////////////////////////
  187. module pluggableContainer00()
  188. {
  189. makeBody00();
  190. rotate([180,0,0])
  191. translate([0,2*totalWid,-totalHei])
  192. makeLid00();
  193. }
  194. ////////////////////////////////////////////////////////////////////
  195. module pluggableContainer01()
  196. {
  197. makeBody01();
  198. rotate([180,0,0])
  199. translate([0,2*totalWid,-totalHei])
  200. makeLid01();
  201. }
  202. ////////////////////////////////////////////////////////////////////
  203. module pluggableContainer02()
  204. {
  205. makeBody02();
  206. rotate([180,0,0])
  207. translate([0,2*totalWid,-totalHei])
  208. makeLid02();
  209. }
  210. ////////////////////////////////////////////////////////////////////
  211. module makeBody00()
  212. {
  213. union()
  214. {
  215. // exterior part
  216. cutTop(totalHei-lidHei)
  217. difference()
  218. {
  219. roundedBox00(totalHei, filletRad)
  220. makeBase00(totalLen, totalWid, sideRad);
  221. translate([0,0,wallThic/2])
  222. roundedBox00(totalHei, filletRad)
  223. offset(-wallThic/2)
  224. makeBase00(totalLen, totalWid, sideRad);
  225. }
  226. // interior part
  227. cutTop(totalHei-lidHei+lidOve)
  228. translate([0,0,wallThic/2])
  229. difference()
  230. {
  231. roundedBox00(totalHei, filletRad)
  232. offset(-wallThic/2)
  233. makeBase00(totalLen, totalWid, sideRad);
  234. translate([0,0,wallThic/2])
  235. roundedBox00(totalHei, filletRad)
  236. offset(-wallThic)
  237. makeBase00(totalLen, totalWid, sideRad);
  238. }
  239. }
  240. }
  241. ////////////////////////////////////////////////////////////////////
  242. module makeBody01()
  243. {
  244. union()
  245. {
  246. // exterior part
  247. cutTop(totalHei-lidHei)
  248. translate([0,0,filletRad])
  249. difference()
  250. {
  251. roundObject(filletRad)
  252. roundedBox00(totalHei, filletRad)
  253. offset(-filletRad)
  254. makeBase00(totalLen, totalWid, sideRad);
  255. translate([0,0,wallThic/2])
  256. roundObject(filletRad)
  257. roundedBox00(totalHei, filletRad)
  258. offset(-wallThic/2-filletRad)
  259. makeBase00(totalLen, totalWid, sideRad);
  260. }
  261. // interior part
  262. cutTop(totalHei-lidHei+lidOve)
  263. translate([0,0,wallThic/2+filletRad])
  264. difference()
  265. {
  266. roundObject(filletRad)
  267. roundedBox00(totalHei, filletRad)
  268. offset(-wallThic/2-filletRad)
  269. makeBase00(totalLen, totalWid, sideRad);
  270. translate([0,0,wallThic/2])
  271. roundObject(filletRad)
  272. roundedBox00(totalHei, filletRad)
  273. offset(-wallThic-filletRad)
  274. makeBase00(totalLen, totalWid, sideRad);
  275. }
  276. }
  277. }
  278. ////////////////////////////////////////////////////////////////////
  279. module makeBody02()
  280. {
  281. halfWall=wallThic/2; // the total hull is a sum of exterior and interiour part
  282. union()
  283. {
  284. // exterior part
  285. cutTop(totalHei-lidHei)
  286. difference()
  287. {
  288. roundedBox01(totalLen, totalWid, totalHei, topRad, filletRad);
  289. translate([0,0,halfWall])
  290. roundedBox01(totalLen-wallThic, totalWid-wallThic,
  291. totalHei-wallThic, topRad-wallThic/2, filletRad);
  292. }
  293. // interior part
  294. cutTop(totalHei-lidHei+lidOve)
  295. difference()
  296. {
  297. roundedBox01(totalLen-wallThic+0.001, totalWid-wallThic+0.001,
  298. totalHei-wallThic+0.001, topRad-wallThic/2+0.0005, filletRad);
  299. translate([0,0,halfWall])
  300. roundedBox01(totalLen-2*wallThic, totalWid-2*wallThic,
  301. totalHei-2*wallThic, topRad-wallThic, filletRad);
  302. }
  303. }
  304. }
  305. ////////////////////////////////////////////////////////////////////
  306. ////////////////////////////////////////////////////////////////////
  307. module makeLid00()
  308. {
  309. union()
  310. {
  311. // exterior part
  312. cutBottom(totalHei-lidHei)
  313. difference()
  314. {
  315. roundedBox00(totalHei, filletRad)
  316. offset(clearence)
  317. makeBase00(totalLen, totalWid, sideRad);
  318. translate([0,0,-wallThic/2])
  319. roundedBox00(totalHei, filletRad)
  320. offset(-wallThic/2+clearence)
  321. makeBase00(totalLen, totalWid, sideRad);
  322. }
  323. // interior part
  324. cutBottom(totalHei-lidHei+lidOve)
  325. translate([0,0,-wallThic/2])
  326. difference()
  327. {
  328. roundedBox00(totalHei, filletRad)
  329. offset(-wallThic/2+clearence)
  330. makeBase00(totalLen, totalWid, sideRad);
  331. translate([0,0,-wallThic/2])
  332. roundedBox00(totalHei, filletRad)
  333. offset(-wallThic+clearence)
  334. makeBase00(totalLen, totalWid, sideRad);
  335. }
  336. }
  337. }
  338. ////////////////////////////////////////////////////////////////////
  339. module makeLid01()
  340. {
  341. union()
  342. {
  343. // exterior part
  344. cutBottom(totalHei-lidHei)
  345. translate([0,0,-filletRad])
  346. difference()
  347. {
  348. roundObject(filletRad)
  349. roundedBox00(totalHei, filletRad)
  350. offset(-filletRad+clearence)
  351. makeBase00(totalLen, totalWid, sideRad);
  352. translate([0,0,-wallThic/2])
  353. roundObject(filletRad)
  354. roundedBox00(totalHei, filletRad)
  355. offset(-wallThic/2-filletRad+clearence)
  356. makeBase00(totalLen, totalWid, sideRad);
  357. }
  358. // interior part
  359. cutBottom(totalHei-lidHei+lidOve)
  360. translate([0,0,-wallThic/2-filletRad])
  361. difference()
  362. {
  363. roundObject(filletRad)
  364. roundedBox00(totalHei, filletRad)
  365. offset(-wallThic/2-filletRad+clearence)
  366. makeBase00(totalLen, totalWid, sideRad);
  367. translate([0,0,-wallThic/2])
  368. roundObject(filletRad)
  369. roundedBox00(totalHei, filletRad)
  370. offset(-wallThic-filletRad+clearence)
  371. makeBase00(totalLen, totalWid, sideRad);
  372. }
  373. }
  374. }
  375. ////////////////////////////////////////////////////////////////////
  376. module makeLid02()
  377. {
  378. halfWall=wallThic/2.0; // the total hull is a sum of exterior and interiour part
  379. union()
  380. {
  381. // exterior part
  382. cutBottom(totalHei-lidHei)
  383. difference()
  384. {
  385. roundedBox01(totalLen+2*clearence, totalWid+2*clearence, totalHei, topRad, filletRad);
  386. translate([0,0,halfWall-0.01])
  387. roundedBox01(totalLen+2*clearence-wallThic, totalWid+2*clearence-wallThic,
  388. totalHei-wallThic+0.01, topRad-wallThic/2, filletRad);
  389. }
  390. // interior part
  391. cutBottom(totalHei-lidHei+lidOve-halfWall)
  392. difference()
  393. {
  394. roundedBox01(totalLen+2*clearence-wallThic+0.001, totalWid+2*clearence-wallThic+0.001,
  395. totalHei-wallThic+0.001, topRad-wallThic/2+0.0005, filletRad);
  396. translate([0,0,halfWall-0.01])
  397. roundedBox01(totalLen+2*clearence-2*wallThic, totalWid+2*clearence-2*wallThic,
  398. totalHei-2*wallThic+0.01, topRad-wallThic, filletRad);
  399. }
  400. }
  401. }
  402. ////////////////////////////////////////////////////////////////////
  403. ////////////////////////////////////////////////////////////////////
  404. module roundedBox00(height, filletRadius)
  405. {
  406. assert(topRad<=totalLen, "Error: top cuvature may not be greater than length of box.");
  407. intersection()
  408. {
  409. hull()
  410. {
  411. translate([0,0,height-filletRadius])
  412. makeFillet(filletRadius)
  413. offset(-filletRadius)
  414. children(0);
  415. translate([0,0,filletRadius])
  416. makeFillet(filletRadius)
  417. offset(-filletRadius)
  418. children(0);
  419. }
  420. // @see https://de.wikipedia.org/wiki/Kreissegment
  421. //sphereRad=(4h² + s²)/8h = (4*topRad² + length²)/8*topRad
  422. sphereRad= (4*(topRad*topRad) + totalLen*totalLen)/(8*topRad);
  423. translate([0,0,height-sphereRad])
  424. sphere(r=sphereRad, $fn=200);
  425. }
  426. }
  427. ////////////////////////////////////////////////////////////////////
  428. module roundedBox01(length, width, height, topRad, filletRad)
  429. {
  430. filletDia=2*filletRad;
  431. topDia=2*topRad;
  432. hull()
  433. {
  434. translate([0,0,height-topRad])
  435. scale([length, width, topDia])
  436. sphere(d=1);
  437. translate([0, 0, filletRad+0.00005])
  438. minkowski()
  439. {
  440. sphere(r=filletRad);
  441. scale([length-filletDia, width-filletDia, 1]) cylinder(d=1, h=0.0001);
  442. }
  443. }
  444. }
  445. ////////////////////////////////////////////////////////////////////
  446. ////////////////////////////////////////////////////////////////////
  447. module makeBase00(length, width, sideRad)
  448. {
  449. sideDia=2*sideRad;
  450. translate([-length/2+sideRad,0])
  451. hull()
  452. {
  453. translate([length-sideDia,0])
  454. scale([sideDia, width])
  455. circle(d=1);
  456. scale([sideDia, width])
  457. circle(d=1);
  458. }
  459. }
  460. ////////////////////////////////////////////////////////////////////
  461. ////////////////////////////////////////////////////////////////////
  462. // cuts the top of a children away.
  463. module cutTop(height2Cut)
  464. {
  465. difference()
  466. {
  467. children(0);
  468. translate([0, 0, height2Cut+cutSize])
  469. cube(2*cutSize, center=true);
  470. }
  471. }
  472. ////////////////////////////////////////////////////////////////////
  473. // cuts the bottom of a children away.
  474. module cutBottom(height2Cut)
  475. {
  476. difference()
  477. {
  478. children(0);
  479. translate([0, 0, height2Cut-cutSize])
  480. cube(2*cutSize, center=true);
  481. }
  482. }
  483. ////////////////////////////////////////////////////////////////////
  484. // rounds a 3d object with an given radius
  485. module roundObject(radius)
  486. {
  487. minkowski()
  488. {
  489. sphere(radius);
  490. children(0);
  491. }
  492. }