Well, It relly rocks when you have an access to a laser cutter and have some spare acrylic. Some time ago I’ve done this test-tube holder I use in my lab.
Instead of the actual test-tubes I use bottles from ‘bifidum bacterinum’ I used to take whenever I got my stomach screwed by antibiotics. Therefore, I have a sh*tload of ’em. So there goes a photo of the thing:
The source code for the OpenSCAD project is below, licensed under the beer-ware license.
rows=2; cols=5; spacing=2; borderspace_w = 4; borderspace_l = 20; radius=8.5; drill_via=1.6; delta=0.1; TARGET=2; ////////////////////////// length = borderspace_l*2 + spacing + (radius*2+spacing) * cols; width = borderspace_w*2 + spacing + (radius*2+spacing) * rows; module vials(rows,cols,spacing,radius, borderspace_l, borderspace_w, shift) { length = borderspace_l*2 + spacing + (radius*2+spacing) * cols; width = borderspace_w*2 + spacing + (radius*2+spacing) * rows; echo("Vial holder: length: ",length, "width:", width); difference(){ for (j=[0:rows-1]) { for (i=[0:cols-1+ ( j % 2)]) { #translate( [ borderspace_w +radius+spacing + (radius*2+spacing)*j, -shift * (j %2 ) + borderspace_l +radius+spacing + (radius*2+spacing)*i ] ) circle(radius); } } } } difference() { square([width,length]); # translate ([width/4,borderspace_l/3])circle(drill_via); # translate ([3*width/4,borderspace_l/3])circle(drill_via); # translate ([width/4,length-borderspace_l/3])circle(drill_via); # translate ([3*width/4,length-borderspace_l/3])circle(drill_via); # translate ([2*width/20,length/2-radius-spacing/2])circle(drill_via); # translate ([2*width/20,length/2+radius+spacing/2])circle(drill_via); # translate ([18*width/20,length/2])circle(drill_via); } if ( TARGET==1 ) { translate([width+delta,0]) difference(){ square([width,length]); # vials(rows,cols,spacing,radius, borderspace_l, borderspace_w, radius); # translate ([width/4,borderspace_l/3])circle(drill_via); # translate ([3*width/4,borderspace_l/3])circle(drill_via); # translate ([width/4,length-borderspace_l/3])circle(drill_via); # translate ([3*width/4,length-borderspace_l/3])circle(drill_via); # translate ([2*width/20,length/2-radius-spacing/2])circle(drill_via); # translate ([2*width/20,length/2+radius+spacing/2])circle(drill_via); # translate ([18*width/20,length/2])circle(drill_via); } } else { translate([0,0,15]) difference(){ square([width,length]); # vials(rows,cols,spacing,radius, borderspace_l, borderspace_w, radius); # translate ([width/4,borderspace_l/3])circle(drill_via); # translate ([3*width/4,borderspace_l/3])circle(drill_via); # translate ([width/4,length-borderspace_l/3])circle(drill_via); # translate ([2*width/20,length/2-radius-spacing/2])circle(drill_via); # translate ([2*width/20,length/2+radius+spacing/2])circle(drill_via); # translate ([18*width/20,length/2])circle(drill_via); } }