User:Dorkmo/Ideas/Battery/SCAD/201509: Difference between revisions
< User:Dorkmo | Ideas | Battery | SCAD
		
		
		
		Jump to navigation
		Jump to search
		|  (→cage) | |||
| (7 intermediate revisions by the same user not shown) | |||
| Line 3: | Line 3: | ||
| =cage= | =cage= | ||
| *issues | |||
| **cut out below lid doesnt change angle with mesh_angle. fixed at 45.  | |||
|   <nowiki> |   <nowiki> | ||
| height =  | height = 160; | ||
| tub_width =  | tub_width = 38; | ||
| tub_length =  | tub_length = 88; | ||
| basethickness = 5; | basethickness = 5; | ||
| tub_wall = 2; | tub_wall = 2; | ||
| Line 18: | Line 21: | ||
| center_dividers = 00; //1 yes 0 no | center_dividers = 00; //1 yes 0 no | ||
| cage_height = 120; | cage_height = 120; | ||
| cage_wall =  | cage_wall = 7; | ||
| cage_endwall = 2; | cage_endwall = 2; | ||
| cage_base =  | cage_base = 4; | ||
| mesh_opening = 1.875 ; | mesh_opening = 1.875 ; | ||
| Line 32: | Line 35: | ||
| tub_lid_depthinto = 7; | tub_lid_depthinto = 7; | ||
| tub_divot_height = 5.5; | tub_divot_height = 5.5; | ||
| //******************************************* | |||
| //begin underlying cage module | //begin underlying cage module | ||
| Line 255: | Line 260: | ||
| echo("mesh dividers thickness",sin(45)*((mesh_spacing-((sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))))/sin(90))); | echo("mesh dividers thickness",sin(45)*((mesh_spacing-((sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))))/sin(90))); | ||
|  </nowiki> | |||
| =cage lid= | |||
|  <nowiki> | |||
| height = 160; | |||
| tub_width = 38; | |||
| tub_length = 88; | |||
| basethickness = 5; | |||
| tub_wall = 2; | |||
| tub_outsidewall = 4; | |||
| tubs_rows    = 5; | |||
| tubs_columns = 2; | |||
| spacing = 1.940055; | |||
| center_dividers = 00; //1 yes 0 no | |||
| cage_height = 120; | |||
| cage_wall = 7; | |||
| cage_endwall = 2; | |||
| cage_base = 4; | |||
| mesh_opening = 1.875 ; | |||
| mesh_angle = 50; | |||
| mesh_spacing = 4.1; | |||
| wire_count = 9; //number of wires into each cage | |||
| wire_diameter = 1.875; | |||
| wire_holeoffc = 0; | |||
| cage_lid_cut = 0; //1 yes 0 no cavity in lid or not? | |||
| cage_minicleat = 2; | |||
| yn_cage_minicleat = 1; //1 yes 0 no | |||
| yn_cage_cleat = 0; //1 yes 0 no | |||
| cage_lid_depthinto = 7; | |||
| cage_divot_height = 4; | |||
| tub_lid_depthinto = 7; | |||
| tub_divot_height = 5.5; | |||
| shrink_cage_lid = 0.5; | |||
| base_chamfer_depth = 0.9; //max 1.0 | |||
| base_wire_cone = 0.2; //diameter added to wire_diameter | |||
| union() | |||
|  { | |||
|   difference() | |||
|    { | |||
|     union() | |||
|      { | |||
|       translate([shrink_cage_lid/2,shrink_cage_lid/2,0]) | |||
|        { | |||
|       cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))-shrink_cage_lid,((tub_length-(spacing*2))-(cage_endwall*2))-shrink_cage_lid,cage_lid_depthinto], center=false); | |||
|        } | |||
|       translate([-1,-1,cage_lid_depthinto]) | |||
|        { | |||
|         cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+2,((tub_length-(spacing*2))-(cage_endwall*2))+2,2], center=false); | |||
|        } | |||
| //spheres lock ins | |||
| //1 | |||
|       translate([(shrink_cage_lid/2),((tub_length-(spacing*2))-(cage_endwall*2))*1/4,((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2)]) | |||
|        { | |||
|         divot_sphere(); | |||
|        } | |||
| //2 | |||
|       translate([(shrink_cage_lid/2),((tub_length-(spacing*2))-(cage_endwall*2))*3/4,((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2)]) | |||
|        { | |||
|         divot_sphere(); | |||
|        } | |||
| //3 | |||
|       translate([(((tub_width-(spacing*3))/2)-(cage_endwall*2))-(shrink_cage_lid/2),((tub_length-(spacing*2))-(cage_endwall*2))*1/4,((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2)]) | |||
|        { | |||
|         mirror([1,0,0]) | |||
|          { | |||
|           divot_sphere(); | |||
|          } | |||
|        } | |||
| //4 | |||
|       translate([(((tub_width-(spacing*3))/2)-(cage_endwall*2))-(shrink_cage_lid/2),((tub_length-(spacing*2))-(cage_endwall*2))*3/4,((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2)]) | |||
|        { | |||
|         mirror([1,0,0]) | |||
|          { | |||
|           divot_sphere(); | |||
|          } | |||
|        } | |||
| //end spheres | |||
| //minicleats | |||
| //1 | |||
| translate([(((((((tub_width-(spacing*3))/2)-(cage_endwall*2))+2)/2)-cage_minicleat)+((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2)-(cage_minicleat),((((tub_length-(spacing*2))-(cage_endwall*2))*1/2))+(wire_diameter/2),cage_lid_depthinto+2]) | |||
|    { | |||
| for(w = [-(wire_count-1)/2 : (wire_count-1)/2]) | |||
|  { | |||
|   translate(w*[0,((((tub_length-(spacing*2))-(cage_endwall*2)-2))/(wire_count+1)),0]) | |||
|    { | |||
| if (yn_cage_minicleat==1) mini_cleat(cage_minicleat,1); | |||
| } | |||
| } | |||
| } | |||
| //2 | |||
| translate([((cage_minicleat)-((((((tub_width-(spacing*3))/2)-(cage_endwall*2))+2)/2)-cage_minicleat)+((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2),((((tub_length-(spacing*2))-(cage_endwall*2))*1/2))+(wire_diameter/2),cage_lid_depthinto+2]) | |||
|    { | |||
| mirror([1,0,0]) | |||
| { | |||
| for(w = [-(wire_count-1)/2 : (wire_count-1)/2]) | |||
|  { | |||
|   translate(w*[0,((((tub_length-(spacing*2))-(cage_endwall*2)-2))/(wire_count+1)),0]) | |||
|    { | |||
| if (yn_cage_minicleat==1) mini_cleat(cage_minicleat,1); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //end mini cleats | |||
|      } | |||
| //end union begin difference | |||
|   translate([1,1,1]) | |||
|    { | |||
|     if (cage_lid_cut==1) cube(size = [((tub_width-(spacing*3))/2)-(cage_endwall*2)-2,(tub_length-(spacing*2))-(cage_endwall*2)-2,cage_lid_depthinto+3], center=false); | |||
|    } | |||
| //chamfer underside of lip | |||
|   translate([-2,-1,cage_lid_depthinto-1]) | |||
|    { | |||
|     rotate([45,0,0]) | |||
|      { | |||
|       cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false); | |||
|      } | |||
|    } | |||
|   translate([-2,(tub_length-(spacing*2))-(cage_endwall*2)+1,cage_lid_depthinto-1]) | |||
|    { | |||
|     rotate([45,0,0]) | |||
|      { | |||
|       cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false); | |||
|      } | |||
|    } | |||
|   translate([-1,-2,cage_lid_depthinto-1]) | |||
|    { | |||
|     rotate([45,0,90]) | |||
|      { | |||
|       cube(size = [((tub_length-(spacing*2))-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false); | |||
|      } | |||
|    } | |||
|   translate([(((tub_width-(spacing*3))/2)-(cage_endwall*2))+1,-2,cage_lid_depthinto-1]) | |||
|    { | |||
|     rotate([45,0,90]) | |||
|      { | |||
|       cube(size = [((tub_length-(spacing*2))-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false); | |||
|      } | |||
|    } | |||
| //end chamfer | |||
| //chamfer base | |||
|   translate([-2,base_chamfer_depth-1,-1]) | |||
|    { | |||
|     rotate([45,0,0]) | |||
|      { | |||
|       #cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false); | |||
|      } | |||
|    } | |||
|   translate([-2,(tub_length-(spacing*2))-(cage_endwall*2)+1-base_chamfer_depth,-1]) | |||
|    { | |||
|     rotate([45,0,0]) | |||
|      { | |||
|       #cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false); | |||
|      } | |||
|    } | |||
|   translate([-1+base_chamfer_depth,-2,-1]) | |||
|    { | |||
|     rotate([45,0,90]) | |||
|      { | |||
|       #cube(size = [((tub_length-(spacing*2))-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false); | |||
|      } | |||
|    } | |||
|   translate([(((tub_width-(spacing*3))/2)-(cage_endwall*2))+1-base_chamfer_depth,-2,-1]) | |||
|    { | |||
|     rotate([45,0,90]) | |||
|      { | |||
|       #cube(size = [((tub_length-(spacing*2))-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false); | |||
|      } | |||
|    } | |||
| //end chamfer | |||
| //begin wire holes | |||
|   translate([((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2,(((tub_length-(spacing*2))-(cage_endwall*2))*1/2),-1]) | |||
|    { | |||
| for(w = [-(wire_count-1)/2 : (wire_count-1)/2]) | |||
|  { | |||
|   translate(w*[0,((((tub_length-(spacing*2))-(cage_endwall*2)-2))/(wire_count+1)),0]) | |||
|    { | |||
| //wire hole | |||
|     #cylinder(r2 = wire_diameter/2, r1 = (wire_diameter+base_wire_cone)/2, h = cage_lid_depthinto+2+2); | |||
|    } | |||
|  }  | |||
|    } | |||
| //end wire holes | |||
| //end difference | |||
|  } | |||
| //begin union | |||
| //cleat | |||
|     translate([((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2,(((tub_length-(spacing*2))-(cage_endwall*2))*1/2)-(wire_diameter*1.5)-1+wire_holeoffc,0]) | |||
|      { | |||
|         if (yn_cage_cleat==1) cleat(2,cage_lid_depthinto+2); | |||
|      } | |||
|     translate([((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2,(((tub_length-(spacing*2))-(cage_endwall*2))*1/2)+(wire_diameter*1.5)+1+wire_holeoffc,0]) | |||
|      { | |||
|       mirror([0,1,0]) | |||
|        { | |||
|         if (yn_cage_cleat==1) cleat(2,cage_lid_depthinto+2); | |||
|        } | |||
|      } | |||
| //end cleat | |||
| } | |||
| //divot | |||
| module divot_sphere() | |||
| { | |||
| difference() | |||
| { | |||
| translate([(cage_divot_height/2)/sin(45)*sin(45),0,0]) | |||
| { | |||
| sphere(r = (cage_divot_height/2)/sin(45)); | |||
| } | |||
| translate([(cage_divot_height/2)/sin(45),0,0]) | |||
| cube(size = [((cage_divot_height/2)/sin(45)*2),((cage_divot_height/2)/sin(45)*2),((cage_divot_height/2)/sin(45)*2)], center=true); | |||
| } | |||
| } | |||
| ////cleat module | |||
| module cleat(size,height) | |||
|  { | |||
|   translate([0,0,-size]) | |||
|   { | |||
|   difference() | |||
|    { | |||
|     rotate([45,0,0]) | |||
|      { | |||
|       rotate([0,0,45]) | |||
|        { | |||
|         cube(size = [size,size,height/sin(45)], center=false); | |||
|        } | |||
|      } | |||
|     translate([-size*3/2,-size*3/2,0]) | |||
|      { | |||
|       #cube(size = [size*3,size*3,size],center=false); | |||
|      } | |||
|    } | |||
|  } | |||
| } | |||
| //end cleat | |||
| //mini_cleat module | |||
| module mini_cleat(sides,height) | |||
| { | |||
| union() | |||
| { | |||
| #cube(size = [sides,sides,height]); | |||
| translate([0,0,height]) | |||
| { | |||
| polyhedron | |||
|   (points = [ [0,0,0],[sides,0,0],[sides,sides,0],[0,sides,0], | |||
|            [sides,0,sides],[sides*2,0,sides],[sides*2,sides,sides],[sides,sides,sides] | |||
|          ], | |||
|   faces = [ [0,1,2],[0,2,3], // | |||
|           [0,5,1],[0,4,5],   // | |||
|           [1,5,6],[1,6,2],    | |||
|           [2,6,7],[2,7,3], | |||
|           [3,7,4],[3,4,0], | |||
|           [4,7,6],[4,6,5] | |||
|         ] | |||
| ); | |||
| } | |||
| } | |||
| } | |||
| //end mini cleat module | |||
|   </nowiki> |   </nowiki> | ||
| =tub= | =tub= | ||
| *issues | |||
| **aligning grooves only working for single tub. craps out with multiple cells. | |||
| **side eyelets mess up on one side when trying to move in and out | |||
| **might make internal corners rounded just to look nice | |||
| **first print had laminated cracks | |||
| ***located where grooves meet at corners | |||
| ***might shift grooves down a few milimeters relative to the previous side | |||
| ***might make interal corners  of tub rounded using a Minkowski sum | |||
|   <nowiki> |   <nowiki> | ||
| height =  | height = 160; | ||
| tub_width =  | tub_width = 38; | ||
| tub_length =  | tub_length = 88; | ||
| basethickness = 5; | basethickness = 5; | ||
| tub_wall = 2; | tub_wall = 2; | ||
| tub_outsidewall =  | tub_outsidewall = 4; | ||
| tub_wallgroovedepth = 2 | tub_wallgroovedepth = 2; | ||
| tub_wallgroovewidth =  | tub_wallgroovewidth = 15; | ||
| tub_wallgroovecorners = | tub_wallgroovecorners =4; | ||
| grooves_yn = 1; //1 yes 0 no | grooves_yn = 1; //1 yes 0 no | ||
| Line 292: | Line 592: | ||
| wall_spacers_yn = 0; //1 yes 0 no | wall_spacers_yn = 0; //1 yes 0 no | ||
| center_dividers = 0; //1 yes 0 no | center_dividers = 0; //1 yes 0 no | ||
| cage_height =  | cage_height = 120; | ||
| cage_wall =  | cage_wall = 7; | ||
| cage_endwall = 2; | cage_endwall = 2; | ||
| cage_base =  | cage_base = 4; | ||
| mesh_opening = 1. | mesh_opening = 1.875 ; | ||
| mesh_angle =  | mesh_angle = 50; | ||
| mesh_spacing =  | mesh_spacing = 4.1; | ||
| wire_diameter = 2; | wire_diameter = 2; | ||
| Line 307: | Line 607: | ||
| tub_lid_depthinto = 7; | tub_lid_depthinto = 7; | ||
| tub_divot_height = 5.5; | tub_divot_height = 5.5; | ||
| //******************************************* | |||
| tub_wallgroovewidthactual=((2*(tub_width+(2*tub_outsidewall)-tub_wallgroovecorners))+(2*(tub_length+(2*tub_outsidewall)-tub_wallgroovecorners)))/(2*round(((2*(tub_width+(2*tub_outsidewall)-tub_wallgroovecorners))+(2*(tub_length+(2*tub_outsidewall)-tub_wallgroovecorners)))/(2*tub_wallgroovewidth))); | tub_wallgroovewidthactual=((2*(tub_width+(2*tub_outsidewall)-tub_wallgroovecorners))+(2*(tub_length+(2*tub_outsidewall)-tub_wallgroovecorners)))/(2*round(((2*(tub_width+(2*tub_outsidewall)-tub_wallgroovecorners))+(2*(tub_length+(2*tub_outsidewall)-tub_wallgroovecorners)))/(2*tub_wallgroovewidth))); | ||
| Line 922: | Line 1,224: | ||
|      { |      { | ||
|       cube(size = [((spacing/(1-cos(45)))*2)+1,((spacing/(1-cos(45)))*2),((spacing/(1-cos(45)))*2)+spacing+1], center=true); |       cube(size = [((spacing/(1-cos(45)))*2)+1,((spacing/(1-cos(45)))*2),((spacing/(1-cos(45)))*2)+spacing+1], center=true); | ||
| //trim bottom | |||
|        translate([0,(-((spacing/(1-cos(45)))*2)/2)-spacing,(-(spacing/(1-cos(45)))*cos(45))-1]) | |||
|         { | |||
|          rotate([90,45,90]) | |||
|           { | |||
|            #cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+spacing*2],center=true); | |||
|           }//end rotate bottom | |||
|         }//end translate bottom | |||
|      } |      } | ||
|    }//end difference |    }//end difference | ||
| Line 962: | Line 1,272: | ||
| } | } | ||
| //end divot | //end divot | ||
Latest revision as of 14:23, 25 September 2015
cage
- issues
- cut out below lid doesnt change angle with mesh_angle. fixed at 45.
 
height = 160;
tub_width = 38;
tub_length = 88;
basethickness = 5;
tub_wall = 2;
tub_outsidewall = 4;
tubs_rows    = 5;
tubs_columns = 2;
spacing = 1.940055;
center_dividers = 00; //1 yes 0 no
cage_height = 120;
cage_wall = 7;
cage_endwall = 2;
cage_base = 4;
mesh_opening = 1.875 ;
mesh_angle = 50;
mesh_spacing = 4.1;
wire_diameter = 2;
wire_holeoffc = 0;
cage_lid_depthinto = 7;
cage_divot_height = 4;
tub_lid_depthinto = 7;
tub_divot_height = 5.5;
//*******************************************
//begin underlying cage module
module cage()
 {
  union()
   {
    difference()
     {
      cube(size = [(tub_width-(spacing*3))/2,tub_length-(spacing*2),cage_height], center=false);
//cut hole for powder to sit in
       translate([cage_wall, cage_endwall, cage_base])
        cube(size = [((tub_width-(spacing*3))/2)-(cage_wall*2)+0.001,(tub_length-(spacing*2))-(cage_endwall*2),cage_height-cage_base+1], center=false);
//cut rectangle hole for lid         
       translate([cage_endwall, cage_endwall, cage_height-cage_lid_depthinto])
        cube(size = [((tub_width-(spacing*3))/2)-(cage_endwall*2)+0.001,(tub_length-(spacing*2))-(cage_endwall*2),cage_lid_depthinto], center=false);
//cut angled hole for lid space
//should probably make angle match mesh angle
       translate([(((tub_width-(spacing*3))/2)/2), ((tub_length-(spacing*2))/2), cage_height-cage_lid_depthinto])
        rotate([0,45,0])
        cube(size = [(cos(45)*(((tub_width-(spacing*3))/2)-(cage_endwall*2)+0.001)),(tub_length-(spacing*2))-(cage_endwall*2),(cos(45)*(((tub_width-(spacing*3))/2)-(cage_endwall*2)+0.001))], center=true);         
         
     }
   }//end difference begin union
//side locking divots
//1
translate([((tub_width-(spacing*3))/2)/2,0,((tub_width-(spacing*3))/2)/2])
rotate([0,0,90])
divot_sphere_d();
//2
translate([((tub_width-(spacing*3))/2)/2,0,cage_height-(((tub_width-(spacing*3))/2)/2)])
rotate([0,0,90])
divot_sphere_d();
//3
translate([((tub_width-(spacing*3))/2)/2,tub_length-(spacing*2),((tub_width-(spacing*3))/2)/2])
rotate([0,0,270])
divot_sphere_d();
//4
translate([((tub_width-(spacing*3))/2)/2,tub_length-(spacing*2),cage_height-(((tub_width-(spacing*3))/2)/2)])
rotate([0,0,270])
divot_sphere_d();
 }//end union
//end cage
     
//begin mesh hole grid module
module holes()
 {
intersection()
{
translate([0,-(sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening))),0])
cube([cage_wall+0.2,1+((((tub_length-(spacing*2))-(cage_endwall*2)))),cage_height], center=false);
//need to translate closer to the cube here with llarge holes
translate([0,0,-mesh_spacing])
{
rotate([0,-mesh_angle,0])
scale([1,1,(sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))/(((sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))/sin(90-mesh_angle))*sin(90))])
{
//for - pair of rows to height
//could simplify
  for (h = [1 : floor((((cage_height-cage_base-((((((sin(90)*(cage_wall/sin(90-mesh_angle))))-((sin(mesh_angle)*((sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))/(sin(90))))))/sin(90))*sin(mesh_angle)))))-cage_lid_depthinto)/mesh_spacing)])
   {
    translate(h*[0,0,mesh_spacing])
{
//for - second row
 for (w = [1 : floor((((tub_length-(spacing*2))-(cage_endwall*2))-(sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening))))/mesh_spacing)])
        {
//translate second row
         translate([0,-mesh_spacing/2,mesh_spacing/2])
           {
//make second row copies
            translate(w*[0,mesh_spacing,0])
             {
              rotate([45,0,0])
               {
    cube(size = [(cage_wall*2)+(cage_height/sin(90))*sin(mesh_angle),mesh_opening,mesh_opening], center=false);
               }
             }
           }
         }
//for - create first row
for (w = [0 : floor((((tub_length-(spacing*2))-(cage_endwall*2))-(sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening))))/mesh_spacing)])
             {
              translate(w*[0,mesh_spacing,0])
 {
  rotate([45,0,0])
   { 
//need to tweak
    cube(size = [(cage_wall*2)+(cage_height/sin(90))*sin(mesh_angle),mesh_opening,mesh_opening],center=false);
   }
 }
}
}
}
}
////end cube
}
}
}
////end mesh hole grid module
//////divot
module divot_sphere()
{
difference()
{
translate([(cage_divot_height/2)/sin(45)*sin(45),0,0])
{
sphere(r = (cage_divot_height/2)/sin(45));
}
translate([(cage_divot_height/2)/sin(45),0,0])
cube(size = [((cage_divot_height/2)/sin(45)*2),((cage_divot_height/2)/sin(45)*2),((cage_divot_height/2)/sin(45)*2)], center=true);
}
}
////end divot module
//begin final cage construction
difference()
 {
  cage();
//begin holes
  translate([(((tub_width-(spacing*3))/2)-cage_wall)+0.0, cage_endwall+((sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))/2)+(((((tub_length-(spacing*2))-(cage_endwall*2))-(((floor((((tub_length-(spacing*2))-(cage_endwall*2))-(sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening))))/mesh_spacing))*mesh_spacing)+sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))))/2), cage_base])
   {
    holes();
   }
    translate([(cage_wall)-0.0,cage_endwall+((sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))/2)+(((((tub_length-(spacing*2))-(cage_endwall*2))-(((floor((((tub_length-(spacing*2))-(cage_endwall*2))-(sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening))))/mesh_spacing))*mesh_spacing)+sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))))/2), cage_base])
   {
  mirror([1,0,0])
     {
      #holes();
     }
   }
//end holes
//begin divots
//1
      translate([cage_endwall,(((tub_length-(spacing*2))-(cage_endwall*2))*1/4)+cage_endwall,cage_height-(((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2))])
       {
        #divot_sphere();
       }
//2
      translate([cage_endwall,(((tub_length-(spacing*2))-(cage_endwall*2))*3/4)+cage_endwall,cage_height-(((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2))])
       {
        #divot_sphere();
       }
//3
      translate([cage_endwall+(((tub_width-(spacing*3))/2)-(cage_endwall*2)),(((tub_length-(spacing*2))-(cage_endwall*2))*1/4)+cage_endwall,cage_height-(((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2))])
       {
        mirror([1,0,0])
         {
          #divot_sphere();
         }
       }
//4
      translate([cage_endwall+(((tub_width-(spacing*3))/2)-(cage_endwall*2)),(((tub_length-(spacing*2))-(cage_endwall*2))*3/4)+cage_endwall,cage_height-(((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2))])
       {
        mirror([1,0,0])
         {
          #divot_sphere();
         }
       }
//end divots
 }
//end cage
//divot by depth module
module divot_sphere_d()
 {
  translate([0,0,0])
   {
    difference()
     {
      translate([(spacing/(1-cos(45)))*sin(45),0,0])
       {
        sphere(r = (spacing/(1-cos(45))));
       }
      translate([(spacing/(1-cos(45))),0,0])
       {
        cube(size = [((spacing/(1-cos(45)))*2),((spacing/(1-cos(45)))*2),((spacing/(1-cos(45)))*2)], center=true);
       }       
     }
   }
 }
//end divot module
//calculate mesh wall minimum thickness
echo(sin(45)*((mesh_spacing-((sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))))/sin(90)));
//calculate verticle height of mesh holes to take away from max height of holes
//works okay up to 45 then bugs out. might be because its before the scale down
echo((((((sin(90)*(cage_wall/sin(90-mesh_angle))))-((sin(mesh_angle)*((sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))/(sin(90))))))/sin(90))*sin(mesh_angle)));
echo("cage cavity y",((tub_width-(spacing*3))/2)-(cage_wall*2));
echo("cage cavity x",(tub_length-(spacing*2))-(cage_endwall*2));
echo("cage cavity z",cage_height-cage_base);
echo("powder volume per cage",((((tub_width-(spacing*3))/2)-(cage_wall*2)))/10*(((tub_length-(spacing*2))-(cage_endwall*2)))/10*(cage_height-cage_base-cage_lid_depthinto)/10,"cm3");
echo("grams nickle hydroxide per cage",(((((tub_width-(spacing*3))/2)-(cage_wall*2)))/10*(((tub_length-(spacing*2))-(cage_endwall*2)))/10*(cage_height-cage_base-cage_lid_depthinto)/10)*(4.10),"grams");//density is 4.10
echo("total grams nickle hydroxide",(((((tub_width-(spacing*3))/2)-(cage_wall*2)))/10*(((tub_length-(spacing*2))-(cage_endwall*2)))/10*(cage_height-cage_base-cage_lid_depthinto)/10)*(4.10)*(tubs_columns*tubs_rows),"grams");
//calculate mesh wall minimum thickness
echo("mesh dividers thickness",sin(45)*((mesh_spacing-((sqrt((mesh_opening*mesh_opening)+(mesh_opening*mesh_opening)))))/sin(90)));
 
 
 
 
cage lid
height = 160;
tub_width = 38;
tub_length = 88;
basethickness = 5;
tub_wall = 2;
tub_outsidewall = 4;
tubs_rows    = 5;
tubs_columns = 2;
spacing = 1.940055;
center_dividers = 00; //1 yes 0 no
cage_height = 120;
cage_wall = 7;
cage_endwall = 2;
cage_base = 4;
mesh_opening = 1.875 ;
mesh_angle = 50;
mesh_spacing = 4.1;
wire_count = 9; //number of wires into each cage
wire_diameter = 1.875;
wire_holeoffc = 0;
cage_lid_cut = 0; //1 yes 0 no cavity in lid or not?
cage_minicleat = 2;
yn_cage_minicleat = 1; //1 yes 0 no
yn_cage_cleat = 0; //1 yes 0 no
cage_lid_depthinto = 7;
cage_divot_height = 4;
tub_lid_depthinto = 7;
tub_divot_height = 5.5;
shrink_cage_lid = 0.5;
base_chamfer_depth = 0.9; //max 1.0
base_wire_cone = 0.2; //diameter added to wire_diameter
union()
 {
  difference()
   {
    union()
     {
      translate([shrink_cage_lid/2,shrink_cage_lid/2,0])
       {
      cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))-shrink_cage_lid,((tub_length-(spacing*2))-(cage_endwall*2))-shrink_cage_lid,cage_lid_depthinto], center=false);
       }
      translate([-1,-1,cage_lid_depthinto])
       {
        cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+2,((tub_length-(spacing*2))-(cage_endwall*2))+2,2], center=false);
       }
//spheres lock ins
//1
      translate([(shrink_cage_lid/2),((tub_length-(spacing*2))-(cage_endwall*2))*1/4,((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2)])
       {
        divot_sphere();
       }
//2
      translate([(shrink_cage_lid/2),((tub_length-(spacing*2))-(cage_endwall*2))*3/4,((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2)])
       {
        divot_sphere();
       }
//3
      translate([(((tub_width-(spacing*3))/2)-(cage_endwall*2))-(shrink_cage_lid/2),((tub_length-(spacing*2))-(cage_endwall*2))*1/4,((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2)])
       {
        mirror([1,0,0])
         {
          divot_sphere();
         }
       }
//4
      translate([(((tub_width-(spacing*3))/2)-(cage_endwall*2))-(shrink_cage_lid/2),((tub_length-(spacing*2))-(cage_endwall*2))*3/4,((cage_lid_depthinto-cage_divot_height)/2)+(cage_divot_height/2)])
       {
        mirror([1,0,0])
         {
          divot_sphere();
         }
       }
//end spheres
//minicleats
//1
translate([(((((((tub_width-(spacing*3))/2)-(cage_endwall*2))+2)/2)-cage_minicleat)+((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2)-(cage_minicleat),((((tub_length-(spacing*2))-(cage_endwall*2))*1/2))+(wire_diameter/2),cage_lid_depthinto+2])
   {
for(w = [-(wire_count-1)/2 : (wire_count-1)/2])
 {
  translate(w*[0,((((tub_length-(spacing*2))-(cage_endwall*2)-2))/(wire_count+1)),0])
   {
if (yn_cage_minicleat==1) mini_cleat(cage_minicleat,1);
}
}
}
//2
translate([((cage_minicleat)-((((((tub_width-(spacing*3))/2)-(cage_endwall*2))+2)/2)-cage_minicleat)+((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2),((((tub_length-(spacing*2))-(cage_endwall*2))*1/2))+(wire_diameter/2),cage_lid_depthinto+2])
   {
mirror([1,0,0])
{
for(w = [-(wire_count-1)/2 : (wire_count-1)/2])
 {
  translate(w*[0,((((tub_length-(spacing*2))-(cage_endwall*2)-2))/(wire_count+1)),0])
   {
if (yn_cage_minicleat==1) mini_cleat(cage_minicleat,1);
}
}
}
}
//end mini cleats
     }
//end union begin difference
  translate([1,1,1])
   {
    if (cage_lid_cut==1) cube(size = [((tub_width-(spacing*3))/2)-(cage_endwall*2)-2,(tub_length-(spacing*2))-(cage_endwall*2)-2,cage_lid_depthinto+3], center=false);
   }
//chamfer underside of lip
  translate([-2,-1,cage_lid_depthinto-1])
   {
    rotate([45,0,0])
     {
      cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false);
     }
   }
  translate([-2,(tub_length-(spacing*2))-(cage_endwall*2)+1,cage_lid_depthinto-1])
   {
    rotate([45,0,0])
     {
      cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false);
     }
   }
  translate([-1,-2,cage_lid_depthinto-1])
   {
    rotate([45,0,90])
     {
      cube(size = [((tub_length-(spacing*2))-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false);
     }
   }
  translate([(((tub_width-(spacing*3))/2)-(cage_endwall*2))+1,-2,cage_lid_depthinto-1])
   {
    rotate([45,0,90])
     {
      cube(size = [((tub_length-(spacing*2))-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false);
     }
   }
//end chamfer
//chamfer base
  translate([-2,base_chamfer_depth-1,-1])
   {
    rotate([45,0,0])
     {
      #cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false);
     }
   }
  translate([-2,(tub_length-(spacing*2))-(cage_endwall*2)+1-base_chamfer_depth,-1])
   {
    rotate([45,0,0])
     {
      #cube(size = [(((tub_width-(spacing*3))/2)-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false);
     }
   }
  translate([-1+base_chamfer_depth,-2,-1])
   {
    rotate([45,0,90])
     {
      #cube(size = [((tub_length-(spacing*2))-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false);
     }
   }
  translate([(((tub_width-(spacing*3))/2)-(cage_endwall*2))+1-base_chamfer_depth,-2,-1])
   {
    rotate([45,0,90])
     {
      #cube(size = [((tub_length-(spacing*2))-(cage_endwall*2))+4,sqrt(2),sqrt(2)], center=false);
     }
   }
//end chamfer
//begin wire holes
  translate([((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2,(((tub_length-(spacing*2))-(cage_endwall*2))*1/2),-1])
   {
for(w = [-(wire_count-1)/2 : (wire_count-1)/2])
 {
  translate(w*[0,((((tub_length-(spacing*2))-(cage_endwall*2)-2))/(wire_count+1)),0])
   {
//wire hole
    #cylinder(r2 = wire_diameter/2, r1 = (wire_diameter+base_wire_cone)/2, h = cage_lid_depthinto+2+2);
   }
 } 
   }
//end wire holes
//end difference
 }
//begin union
//cleat
    translate([((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2,(((tub_length-(spacing*2))-(cage_endwall*2))*1/2)-(wire_diameter*1.5)-1+wire_holeoffc,0])
     {
        if (yn_cage_cleat==1) cleat(2,cage_lid_depthinto+2);
     }
    translate([((((tub_width-(spacing*3))/2)-(cage_endwall*2)))/2,(((tub_length-(spacing*2))-(cage_endwall*2))*1/2)+(wire_diameter*1.5)+1+wire_holeoffc,0])
     {
      mirror([0,1,0])
       {
        if (yn_cage_cleat==1) cleat(2,cage_lid_depthinto+2);
       }
     }
//end cleat
}
//divot
module divot_sphere()
{
difference()
{
translate([(cage_divot_height/2)/sin(45)*sin(45),0,0])
{
sphere(r = (cage_divot_height/2)/sin(45));
}
translate([(cage_divot_height/2)/sin(45),0,0])
cube(size = [((cage_divot_height/2)/sin(45)*2),((cage_divot_height/2)/sin(45)*2),((cage_divot_height/2)/sin(45)*2)], center=true);
}
}
////cleat module
module cleat(size,height)
 {
  translate([0,0,-size])
  {
  difference()
   {
    rotate([45,0,0])
     {
      rotate([0,0,45])
       {
        cube(size = [size,size,height/sin(45)], center=false);
       }
     }
    translate([-size*3/2,-size*3/2,0])
     {
      #cube(size = [size*3,size*3,size],center=false);
     }
   }
 }
}
//end cleat
//mini_cleat module
module mini_cleat(sides,height)
{
union()
{
#cube(size = [sides,sides,height]);
translate([0,0,height])
{
polyhedron
  (points = [ [0,0,0],[sides,0,0],[sides,sides,0],[0,sides,0],
           [sides,0,sides],[sides*2,0,sides],[sides*2,sides,sides],[sides,sides,sides]
         ],
  faces = [ [0,1,2],[0,2,3], //
          [0,5,1],[0,4,5],   //
          [1,5,6],[1,6,2],   
          [2,6,7],[2,7,3],
          [3,7,4],[3,4,0],
          [4,7,6],[4,6,5]
        ]
);
}
}
}
//end mini cleat module
 
tub
- issues
- aligning grooves only working for single tub. craps out with multiple cells.
- side eyelets mess up on one side when trying to move in and out
- might make internal corners rounded just to look nice
- first print had laminated cracks
- located where grooves meet at corners
- might shift grooves down a few milimeters relative to the previous side
- might make interal corners of tub rounded using a Minkowski sum
 
 
height = 160;
tub_width = 38;
tub_length = 88;
basethickness = 5;
tub_wall = 2;
tub_outsidewall = 4;
tub_wallgroovedepth = 2;
tub_wallgroovewidth = 15;
tub_wallgroovecorners =4;
grooves_yn = 1; //1 yes 0 no
eyelets_rowside = 2;
eyelets_columnside = 3;
eyelets_belowtop = 10;
eyelets_walltoceneter = 5;
eyelets_od = 7;
eyelets_id = 3;
eyelets_width = 5;
tubs_rows    = 1;
tubs_columns = 1;
spacing = 1.940055;
wall_spacers_yn = 0; //1 yes 0 no
center_dividers = 0; //1 yes 0 no
cage_height = 120;
cage_wall = 7;
cage_endwall = 2;
cage_base = 4;
mesh_opening = 1.875 ;
mesh_angle = 50;
mesh_spacing = 4.1;
wire_diameter = 2;
wire_holeoffc = 0;
cage_lid_depthinto = 7;
cage_divot_height = 5.5;
tub_lid_depthinto = 7;
tub_divot_height = 5.5;
//*******************************************
tub_wallgroovewidthactual=((2*(tub_width+(2*tub_outsidewall)-tub_wallgroovecorners))+(2*(tub_length+(2*tub_outsidewall)-tub_wallgroovecorners)))/(2*round(((2*(tub_width+(2*tub_outsidewall)-tub_wallgroovecorners))+(2*(tub_length+(2*tub_outsidewall)-tub_wallgroovecorners)))/(2*tub_wallgroovewidth)));
echo("groove width=",tub_wallgroovewidthactual);
echo(tan(45)*(tub_width+(2*tub_outsidewall)-tub_wallgroovecorners)
-(floor((tub_width+(2*tub_outsidewall)-tub_wallgroovecorners)/tub_wallgroovewidthactual)*tub_wallgroovewidthactual));
echo((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth);
echo((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual);
echo((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners);
echo((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/tub_wallgroovewidthactual)*tub_wallgroovewidthactual)));
echo(((((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual)+((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual))-((2*tub_wallgroovewidthactual)*floor(((((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual)+((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual))/(2*tub_wallgroovewidthactual))))));
echo(((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual))
;
union()//eyelets
{
difference()//grooves
{
union()
 {
//tubs
for (c = [0 : tubs_columns-1])
 {
  translate([0,c*(tub_length+tub_wall),0])
   {
    for (r = [0 : tubs_rows-1])
    {
     translate([r*(tub_width+tub_wall),0,0])
      {
       tub();
      }
    }
   }
 }
//end tubs
//outer walls
translate([-tub_outsidewall+tub_wall,-tub_outsidewall+tub_wall,0])
 {
  difference()
   {
    cube(size = [((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall,((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall,height]);
    translate([tub_outsidewall,tub_outsidewall,0])
     {
      cube(size = [(((tub_width+tub_wall)*tubs_rows)+tub_wall)-(tub_wall*2),(((tub_length+tub_wall)*tubs_columns)+tub_wall)-(tub_wall*2),height+1]);
     }
   }
 }
//end outer walls
} //end union
////grooves
//1
rotate([0,0,0])
{
translate([tub_wall-tub_outsidewall+(tub_wallgroovecorners/2),tub_wall-tub_outsidewall,0])
{
if(grooves_yn==1)grooves(tub_wallgroovedepth,tub_wallgroovewidthactual,(((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners,height,0);
}
}
//2
rotate([0,0,90])
{
translate([(tub_wall-tub_outsidewall)+(tub_wallgroovecorners/2),-(tub_wall-tub_outsidewall)-(((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall),0])
{
if(grooves_yn==1)grooves(tub_wallgroovedepth,tub_wallgroovewidthactual,((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall-tub_wallgroovecorners,height,((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual));
}
}
//3
rotate([0,0,180])
{
translate([-(tub_wall-tub_outsidewall)-(tub_wallgroovecorners/2)-((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners),-tub_wall-tub_outsidewall-((((tub_length+tub_wall)*tubs_columns)+tub_wall)-(tub_wall*2)),0])
{
if(grooves_yn==1)grooves(tub_wallgroovedepth,tub_wallgroovewidthactual,(((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners,height,(((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual)+((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual))-((2*tub_wallgroovewidthactual)*floor(((((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual)+((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidthactual*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual))/(2*tub_wallgroovewidthactual)))));
}
}
//4
rotate([0,0,270])
{
translate([-tub_wall-tub_outsidewall-((((tub_length+tub_wall)*tubs_columns)+tub_wall)-(tub_wall*2))+(tub_wallgroovecorners/2),(tub_wall-tub_outsidewall),0])
{
if(grooves_yn==1)grooves(tub_wallgroovedepth,tub_wallgroovewidth,((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall-tub_wallgroovecorners,height,(((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-
(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-
tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual)
+
((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-
(2*tub_wallgroovewidthactual*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-
tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual)
+
((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-
(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-
tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual))
-
((2*tub_wallgroovewidthactual)
*
floor(((((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-
(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-
tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual)
+
((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-
(2*tub_wallgroovewidthactual*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-
tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual)
+
((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-
(2*tub_wallgroovewidthactual*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-
tub_wallgroovecorners)/(2*tub_wallgroovewidthactual))))-tub_wallgroovewidthactual))
/
(2*tub_wallgroovewidthactual)))));
}
}
////end grooves
} //end difference
//begin eyelets
//1 rowside
translate([(tub_wall-tub_outsidewall),(tub_wall-tub_outsidewall)-eyelets_walltoceneter,height-eyelets_belowtop])
{
for (e = [1:eyelets_rowside])
{
translate([(((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)/(eyelets_rowside+1)*e,0,0])
{
rotate([0,0,180])
{
eyelet(eyelets_od,eyelets_id,eyelets_width,tub_wallgroovedepth+eyelets_walltoceneter-(eyelets_od/2));
}
}
}
}
//2
//3
translate([(tub_wall-tub_outsidewall),((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2),height-eyelets_belowtop])
{
for (e = [1:eyelets_rowside])
{
translate([(((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)/(eyelets_rowside+1)*e,0,0])
{
rotate([0,0,0])
{
#eyelet(eyelets_od,eyelets_id,eyelets_width,tub_wallgroovedepth+eyelets_walltoceneter-(eyelets_od/2));
}
}
}
}
//4
//end eyelets
} //end union
//////end render
//////begin modules
////tub module
module tub()
{
union()
{
//walls
 difference()
  {
   cube(size = [tub_width+(tub_wall*2), tub_length+(tub_wall*2), height], center=false);
   translate([tub_wall,tub_wall,basethickness])
    {
     cube(size = [tub_width, tub_length, height-basethickness+1], center=false);
    }
  }
//end walls
//spheres lock ins
//1
      translate([tub_wall,(tub_length*1/4)+tub_wall,height-(((tub_lid_depthinto-tub_divot_height)/2)+(tub_divot_height/2))])
       {
        mirror([1,0,0])
         {
          #divot_sphere();
         }
       }
//2
      translate([tub_wall,(tub_length*3/4)+tub_wall,height-(((tub_lid_depthinto-tub_divot_height)/2)+(tub_divot_height/2))])
       {
        mirror([1,0,0])
         {
          divot_sphere();
         }
       }
//3
      translate([tub_width+tub_wall,(tub_length*1/4)+tub_wall,height-(((tub_lid_depthinto-tub_divot_height)/2)+(tub_divot_height/2))])
       {
        mirror([0,0,0])
         {
          divot_sphere();
         }
       }
//4
      translate([tub_width+tub_wall,(tub_length*3/4)+tub_wall,height-(((tub_lid_depthinto-tub_divot_height)/2)+(tub_divot_height/2))])
       {
        mirror([0,0,0])
         {
          divot_sphere();
         }
       }
//5
      translate([(tub_width*1/2)+tub_wall,tub_wall,height-(((tub_lid_depthinto-tub_divot_height)/2)+(tub_divot_height/2))])
       {
        mirror([0,1,0])
         {
          rotate([0,0,90])
           {
            #divot_sphere();
           }
         }
       }
//6
      translate([(tub_width*1/2)+tub_wall,tub_length+tub_wall,height-(((tub_lid_depthinto-tub_divot_height)/2)+(tub_divot_height/2))])
       {
        mirror([0,0,0])
         {
          rotate([0,0,90])
           {
            #divot_sphere();
           }
         }
       }
//end spheres
//begin locks
translate([(spacing/4)+(tub_width*1/4)+tub_wall,tub_length+tub_wall,basethickness+spacing+(((tub_width-(spacing*3))/2)/2)])
{
#slidelock(spacing);
}
translate([(-spacing/4)+(tub_width*3/4)+tub_wall,tub_length+tub_wall,basethickness+spacing+(((tub_width-(spacing*3))/2)/2)])
{
#slidelock(spacing);
}
translate([(spacing/4)+(tub_width*1/4)+tub_wall,tub_wall,basethickness+spacing+(((tub_width-(spacing*3))/2)/2)])
{
mirror([0,1,0])
{
#slidelock(spacing);
}
}
translate([(-spacing/4)+(tub_width*3/4)+tub_wall,tub_wall,basethickness+spacing+(((tub_width-(spacing*3))/2)/2)])
{
mirror([0,1,0])
{
#slidelock(spacing);
}
}
////upper lock rails
translate([(spacing/4)+(tub_width*1/4)+tub_wall,tub_length+tub_wall,cage_height+basethickness+spacing-(((tub_width-(spacing*3))/2)/2)])
{
#slidelockupper(spacing);
}
translate([(-spacing/4)+(tub_width*3/4)+tub_wall,tub_length+tub_wall,cage_height+basethickness+spacing-(((tub_width-(spacing*3))/2)/2)])
{
#slidelockupper(spacing);
}
translate([(spacing/4)+(tub_width*1/4)+tub_wall,tub_wall,cage_height+basethickness+spacing-(((tub_width-(spacing*3))/2)/2)])
{
mirror([0,1,0])
{
#slidelockupper(spacing);
}
}
translate([(-spacing/4)+(tub_width*3/4)+tub_wall,tub_wall,cage_height+basethickness+spacing-(((tub_width-(spacing*3))/2)/2)])
{
mirror([0,1,0])
{
#slidelockupper(spacing);
}
}
//end locks
}
}
////end tub module
//divider modules
module divider()
 {
  difference()
   {
    union()
     {
      cube(size=[spacing-1,spacing+cage_endwall+2,(spacing+cage_endwall+2)*2]);
      translate([0,0,(spacing+cage_endwall+2)*2])
       {
        rotate([0,45,0])
         {
          cube(size=[(sin(45)*(spacing-1)),spacing+cage_endwall+2,(sin(45)*(spacing-1))]);
         }
       }
     }
    translate([0,spacing+cage_endwall+2,-(((spacing+cage_endwall+2)/sin(45))/sin(45))/2])
     {
      rotate([45,0,0])
       {
        cube(size=[spacing-1,((spacing+cage_endwall+2)/sin(45)),((spacing+cage_endwall+2)/sin(45))]);       
       }
     }
   }
 }
//end divider module
//spacer module
module tub_spacer(length)
 {
translate([-(spacing-1),-length/2,0])
  {
  difference()
   {
    rotate([0,45,0])
     {
      cube(size = [((spacing-1)/sin(45)),length,((spacing-1)/sin(45))]);
     }
    translate([-(spacing-1)-0.1,0,-(spacing-1)])
     {
      #cube(size = [((spacing-1)/sin(45))/sin(45),length,((spacing-1)/sin(45))/sin(45)]);
     }
   }
 }
}
//end spacer
//divot
module divot_sphere()
{
difference()
{
translate([(tub_divot_height/2)/sin(45)*sin(45),0,0])
{
sphere(r = (tub_divot_height/2)/sin(45));
}
translate([(tub_divot_height/2)/sin(45),0,0])
cube(size = [((tub_divot_height/2)/sin(45)*2),((tub_divot_height/2)/sin(45)*2),((tub_divot_height/2)/sin(45)*2)], center=true);
}
}
//end divot module
////groove module
module grooves(tub_wallgroove,groove_width,groove_length,groove_height,groove_shift)
{
translate([((cos(45)*((groove_height/sin(45))+((groove_width*sin(45)*sin(45))/cos(45)))))-height/2,-.0001,height/2])
{
intersection()
{
intersection()
{
for(g = [(-(cos(45)*((groove_height/sin(45))+((groove_width*sin(45)*sin(45))/cos(45))))/groove_width/2) : (groove_length/groove_width/2)])
{
 translate([(g*groove_width*2)+(groove_width*sin(45)*sin(45)),0,groove_shift])
  {
  rotate([0,45,0])
   {
    rotate([0,0,45])
     {
      #cube(size = [groove_width*sin(45)*sin(45),groove_width*sin(45)*sin(45),((groove_height/sin(45))+((groove_width*sin(45)*sin(45))/cos(45)))+(abs(groove_shift/cos(45)*2))], center=true);
     }
   }
  }
}
translate([(-groove_height/2)-(groove_width*sin(45)*sin(45)),0,-groove_height/2])
{
#cube(size = [groove_length,tub_wallgroove,groove_height]);
}
}
translate([((-groove_height/2)-(groove_width*sin(45)*sin(45)))+(groove_length/2),0,0])
{
rotate([0,0,45])
{
cube(size = [groove_length*cos(45),groove_length*cos(45),groove_height],center=true);
}
}
 }//end intersection
}
}
////end groove mdoule
////begin eyelet module
module eyelet(od,id,eyelet_width,standoff)
{
translate([-eyelet_width/2,-(od/2)-standoff,-((od)+od)-standoff+(od/2)])//orgin set at the center of hole cylinder
{
difference()
   {
    union()
     {
      translate([0,standoff,standoff])
       {
        cube(size=[eyelet_width,od,(od/2)+od]);
       }
      translate([0,((od)/2)+standoff,((od/2)+od)+standoff])
       {
        rotate([0,90,0])
         {
          cylinder(r = od/2,h = eyelet_width, $fn=60);
         }
       }
      translate([0,0,0])
       {
        cube(size=[eyelet_width,(od/2)+standoff,((od)+od)+standoff]);
       } 
     }
    translate([-1,eyelet_width+2,-(((eyelet_width+2)/sin(45))/sin(45))/2])
     {
      rotate([45,0,0])
       {
        #cube(size=[eyelet_width+2,((od+standoff+2)/sin(45)),((eyelet_width+2)/sin(45))]);       
       }
     }
      translate([-1,((od)/2)+standoff,((od/2)+od)+standoff])
       {
        rotate([0,90,0])
         {
          cylinder(r = id/2,h = eyelet_width+2, $fn=60);
         }
       }
   }
  }
}
////end eyelet module
////calculations
echo("space above cages for extra fluid is", height-basethickness-spacing-cage_height-tub_lid_depthinto);
echo("tub print area x",((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall);
echo("tub print area y",((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall);
echo("tub print area z",height);
echo("cage cavity y",((tub_width-(spacing*3))/2)-(cage_wall*2));
echo("cage cavity x",(tub_length-(spacing*2))-(cage_endwall*2));
echo("cage cavity z",cage_height-cage_base);
echo("powder volume per cage",((((tub_width-(spacing*3))/2)-(cage_wall*2)))/10*(((tub_length-(spacing*2))-(cage_endwall*2)))/10*(cage_height-cage_base-cage_lid_depthinto)/10,"cm3");
echo("grams nickle hydroxide per cage",(((((tub_width-(spacing*3))/2)-(cage_wall*2)))/10*(((tub_length-(spacing*2))-(cage_endwall*2)))/10*(cage_height-cage_base-cage_lid_depthinto)/10)*(4.10),"grams");//density is 4.10
echo("total grams nickle hydroxide",(((((tub_width-(spacing*3))/2)-(cage_wall*2)))/10*(((tub_length-(spacing*2))-(cage_endwall*2)))/10*(cage_height-cage_base-cage_lid_depthinto)/10)*(4.10)*(tubs_columns*tubs_rows),"grams");
echo(((((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/tub_wallgroovewidth)-floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/tub_wallgroovewidth))*tub_wallgroovewidth)+tub_wallgroovewidth));
//2
echo((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth);
//3
echo((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth);
//2+3
echo(((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth)+((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth));
//(2+3)/absfloor
echo((2*tub_wallgroovewidth)*floor(((((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth)+((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth))/(2*tub_wallgroovewidth))));
//3
echo((((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth)+((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth))-((2*tub_wallgroovewidth)*floor(((((((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_width+tub_wall)*tubs_rows)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth)+((((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)-(2*tub_wallgroovewidth*floor(((((tub_length+tub_wall)*tubs_columns)+(tub_outsidewall*2)-tub_wall)-tub_wallgroovecorners)/(2*tub_wallgroovewidth))))-tub_wallgroovewidth))/(2*tub_wallgroovewidth)))));
//slidelocking module
module slidelock(spacing)
{
 difference()
  {
   translate([0,-spacing,0]) //translate all
    {
//left
     translate([-(spacing/(1-cos(45)))*cos(45),0,-(spacing/(1-cos(45)))*cos(45)])
      {
       rotate([0,0,45])
        {
         cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+spacing*2]);
        }//end rotate left
      }//end translate left
//right
      translate([(spacing/(1-cos(45)))*cos(45),0,-(spacing/(1-cos(45)))*cos(45)])
       {
        rotate([0,0,45])
         {
          cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+spacing*2]);
         }//end rotate right
       }//end translate right
//bottom
       translate([(-(spacing/(1-cos(45)))*cos(45))-spacing,0,-(spacing/(1-cos(45)))*cos(45)])
        {
         rotate([90,45,90])
          {
           cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+spacing*2]);
          }//end rotate bottom
        }//end translate bottom
//bump
        translate([(-(spacing/(1-cos(45)))*cos(45))-spacing,spacing*(2/5),((spacing/(1-cos(45)))*cos(45))-spacing*(2/5)])//set bump fraction
         {
          rotate([90,45,90])
           {
            cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+spacing*2]);
           }//end rotate bump
         }//end translate bump
       
     }//end translate all
//trim left
translate([(-(spacing/(1-cos(45)))*cos(45))-spacing,-spacing*2,(-(spacing/(1-cos(45)))*cos(45))-spacing-1])
{
rotate([0,0,45])
{
cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+(spacing*2)+spacing+2]);
}//end rotate left
}//end translate left
//trim right
translate([((spacing/(1-cos(45)))*cos(45))+spacing,-spacing*2,(-(spacing/(1-cos(45)))*cos(45))-spacing-1])
{
rotate([0,0,45])
{
cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+(spacing*2)+spacing+2]);
}//end rotate right
}//end translate right
//trim back
translate([0,((spacing/(1-cos(45)))*2)/2,spacing/2])
{
cube(size = [((spacing/(1-cos(45)))*2)+1,((spacing/(1-cos(45)))*2),((spacing/(1-cos(45)))*2)+spacing+1], center=true);
}
}//end difference
}///end slidelocking module
//slidelocking module
module slidelockupper(spacing)
{
 difference()
  {
   translate([0,-spacing,0]) //translate all
    {
//left
     translate([-(spacing/(1-cos(45)))*cos(45),0,-(spacing/(1-cos(45)))*cos(45)])
      {
       rotate([0,0,45])
        {
         cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+spacing*2]);
        }//end rotate left
      }//end translate left
//right
     translate([(spacing/(1-cos(45)))*cos(45),0,-(spacing/(1-cos(45)))*cos(45)])
      {
       rotate([0,0,45])
        {
         cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+spacing*2]);
        }//end rotate right
      }//end translate right
    }//end translate all
//trim left
   translate([(-(spacing/(1-cos(45)))*cos(45))-spacing,-spacing*2,(-(spacing/(1-cos(45)))*cos(45))-spacing-1])
    {
     rotate([0,0,45])
      {
       cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+(spacing*2)+spacing+2]);
      }//end rotate left
    }//end translate left
//trim right
   translate([((spacing/(1-cos(45)))*cos(45))+spacing,-spacing*2,(-(spacing/(1-cos(45)))*cos(45))-spacing-1])
    {
     rotate([0,0,45])
      {
       cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+(spacing*2)+spacing+2]);
      }//end rotate right
    }//end translate right
//trim back
   translate([0,((spacing/(1-cos(45)))*2)/2,spacing/2])
    {
     cube(size = [((spacing/(1-cos(45)))*2)+1,((spacing/(1-cos(45)))*2),((spacing/(1-cos(45)))*2)+spacing+1], center=true);
//trim bottom
       translate([0,(-((spacing/(1-cos(45)))*2)/2)-spacing,(-(spacing/(1-cos(45)))*cos(45))-1])
        {
         rotate([90,45,90])
          {
           #cube(size = [(spacing/sin(45)),(spacing/sin(45)),((spacing/(1-cos(45)))*cos(45)*2)+spacing*2],center=true);
          }//end rotate bottom
        }//end translate bottom
    }
  }//end difference
}///end slidelocking module
//divot by depth module
module divot_sphere_d()
 {
  translate([0,0,0])
   {
    difference()
     {
      translate([(spacing/(1-cos(45)))*sin(45),0,0])
       {
        sphere(r = (spacing/(1-cos(45))));
       }
      translate([(spacing/(1-cos(45))),0,0])
       {
        cube(size = [((spacing/(1-cos(45)))*2),((spacing/(1-cos(45)))*2),((spacing/(1-cos(45)))*2)], center=true);
       }       
     }
   }
 }
//end divot module
//divot by height
module divot_sphere()
{
difference()
{
translate([(tub_divot_height/2)/sin(45)*sin(45),0,0])
{
sphere(r = (tub_divot_height/2)/sin(45));
}
translate([(tub_divot_height/2)/sin(45),0,0])
cube(size = [((tub_divot_height/2)/sin(45)*2),((tub_divot_height/2)/sin(45)*2),((tub_divot_height/2)/sin(45)*2)], center=true);
}
}
//end divot
 
tub lid
need include a standard water filling cap with 1/4 turn screw hole. to accommodate something like this [1]