Wickes Treated Studwork (CLS) 38x63x2400mm Single  Product Code: 133657

shed_length = 5184;
shed_width = 1829+305/2;
shed_front_height = 2350;
shed_front_back = 2135;
base_timber = 47;
timber_construct_w = 38;
timber_construct_h = 63;
base_sheet_t = 18;

module cubeI(size,center=false)
{
    echo("Dim: ",size);
    cube(size, center=center);
}

module shedBaseSection(x,y,timber_width=75,timber_length=47, braces=0)
{
    echo("shedBaseSection: x,y,timber_width,timber_length, braces ", x,y,timber_width,timber_length, braces);
    echo("http://www.wickes.co.uk/Wickes-Sawn-Kiln-Dried-47X75-x-3000mm-Single/p/107186#tab-DynamicDeliveryWebTab_content");
    cubeI([x,timber_width,timber_length]);
    translate([0,y-timber_width,0]) cubeI([x,timber_width,timber_length]);
    translate([0,timber_width,0]) cubeI([timber_width,y-timber_width*2,timber_length]);
    translate([x-timber_width,timber_width,0]) cubeI([timber_width,y-timber_width*2,timber_length]);
    if(braces > 0)
    {
        middle_y = y - timber_width*2;
        part_y = middle_y/(braces+1);
        for(loop=[1 : braces ])
        {
                translate([timber_width,timber_width/(braces+1) + (loop*part_y),0]) cubeI([x-timber_width*2, timber_width,timber_length]);
        }
    }
}

module shedBase(x,y,number_x,number_y, braces=1)
{
    for(base_y = [0 : number_y-1])
    {
        for(base_x = [0 : number_x-1])
            {
                translate([base_x*(x/number_x),base_y*(y/number_y),0]) shedBaseSection(x/number_x,y/number_y, braces = braces);
            }
    }
}

module floorMembrane(x,y,thickness,color="Black", overlap=10)
{
    echo("x,y,thickness=1,color, overlap=1",x,y,thickness,color, overlap);
    echo("http://www.screwfix.com/p/dmp-damp-proof-membrane-black-1000ga-3-x-4m/50464#product_additional_details_container");
    translate([-overlap,-overlap,0]) color(color, 0.5) cube([x+overlap*2,y+overlap*2, thickness]);
}

module breatherMembrane(x,y, thickness=0.5)
{
    // google timber frame breather membrane
    rotate([90,0,0])  floorMembrane(x,y,thickness=thickness,color="Black", overlap=thickness);
}

module breatherMembraneSide(x,y, thickness=0.5)
{
    // google timber frame breather membrane

    opp = y-shed_front_back;
    adj = x - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    echo("Degrees: ", theta);
    translate([0,0,0]) rotate([90,0,90]) difference()
    {
        floorMembrane(x,y,thickness=thickness,color="Black", overlap=thickness);
        translate([0,y,-opp/2]) rotate([0,0,-theta]) cube([x+10,opp,opp]);
    }
}

module breatherMembraneFront(x,y, thickness, space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h)
{
    echo ("lll", x,y, thickness, space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h);
    translate([0,0,0]) rotate([90,0,0]) difference()
    {
        floorMembrane(x,y,thickness=thickness,color="Black", overlap=thickness);
        translate([space_to_window_w,space_to_window_h,-100]) rotate([0,0,0]) cube([window_w,window_h,200]);
        translate([space_to_window_w*2+window_w,0,-100]) cube([door_w,door_h,200]);
    }
}

//module shedLowerFloor(x,y, panel_slf_w = 607, panel_slf_l =   1829, panel_slf_t =   5.5, panel_min_dimentions = 100)
module shedLowerFloor(x,y, panel_slf_w = 1220, panel_slf_l = 2440, panel_slf_t = base_sheet_t, panel_min_dimentions = 100)
{
//    echo("http://www.wickes.co.uk/Wickes-Non-Structural-Hardwood-Plywood-5-5x607x1829mm/p/111196");
    echo("http://www.wickes.co.uk/Wickes-General-Purpose-OSB3-Board-18x1220x2440mm/p/110517");
    x_panels = round(-0.5+x/panel_slf_w);
    y_panels = round(-0.5+y/panel_slf_l);
    echo(y_panels);
    if(y_panels>0) // Panel is Not longer than width
    {
        for(base_y = [0 : y_panels-1]) //Truncate not round
        {
            for(base_x = [0 : x_panels-1])
            {
                translate([base_x*panel_slf_w,base_y*panel_slf_l,0]) cubeI([panel_slf_w, panel_slf_l,panel_slf_t]);
                if(y-(panel_slf_l*y_panels) > panel_min_dimentions)
                translate([base_x*panel_slf_w,y_panels*panel_slf_l,0]) cubeI([panel_slf_w, y-(panel_slf_l*y_panels),panel_slf_t]);
                }
            if(x-(panel_slf_w*x_panels) > panel_min_dimentions)
                translate([(x_panels)*panel_slf_w,(y_panels-1)*panel_slf_l,0]) cubeI([x-(panel_slf_w*x_panels), panel_slf_l,panel_slf_t]);
            if(y-(panel_slf_l*y_panels) > panel_min_dimentions)
                translate([(x_panels)*panel_slf_w,y_panels*panel_slf_l,0]) cubeI([x-(panel_slf_w*x_panels), y-(panel_slf_l*y_panels),panel_slf_t]);
        }
    }
    else // Panel is longer than width
    {
     for(base_x = [0 : x_panels-1])
     {
        translate([base_x*panel_slf_w,0,0]) cubeI([panel_slf_w, y,panel_slf_t]);
     }
     if(x-(panel_slf_w*x_panels) > panel_min_dimentions)
                translate([(x_panels)*panel_slf_w,0,0]) cubeI([x-(panel_slf_w*x_panels), y,panel_slf_t]);
    }
}

module verticalStruts(x,z,timber_width=timber_construct_w,timber_length=timber_construct_h, braces=0, beams=0)
{
//    echo("shedBaseSection(x,z,timber_width,timber_length, braces",x,z,timber_width,timber_length, braces);
//    echo("Walls - http://www.wickes.co.uk/Wickes-Sawn-Kiln-Dried-47-x-47-x-2400mm-Pack-6/p/107114");
    cubeI([x,timber_length,timber_width]);
    translate([0,0,z-timber_width]) cubeI([x,timber_length,timber_width]);
    translate([0,0,timber_width]) cubeI([timber_width,timber_length,z-timber_width*2]);
    translate([x-timber_width,0,timber_width]) cubeI([timber_width,timber_length,z-timber_width*2]);
    if(braces > 0)
    {
        middle_z = z - timber_width*2;
        part_z = middle_z/(braces+1);
        for(loop=[1 : braces ])
        {
                translate([timber_width,0,timber_width/(braces+1) + (loop*part_z)]) cubeI([x-timber_width*2,timber_length, timber_width]);
        }
    }
    if(beams> 0)
    {
        middle_x = x - timber_length*2;
        part_x = middle_x/(beams+1);
        for(loop=[1 : beams ])
        {
            translate([timber_length/(beams+1) + (loop*part_x),0,timber_width]) cubeI([timber_width,timber_length,z-timber_width*2]);
        }
    }
}

module backWallStruts(x,z,number_x, braces=1)
{
    echo("backWallStruts(x,z,number_x, braces)",x,z,number_x, braces);
        for(base_x = [0 : number_x-1])
            {
                translate([base_x*(x/number_x),0,0]) verticalStruts(x/number_x,z, braces = braces);
            }
}

module sideWallStruts(x,z,number_x, braces=1)
{
    echo("sideWallStruts(x,z,number_x, braces)",x,z,number_x, braces);
    rotate([0,0,90]) backWallStruts(x,z,number_x, braces);
}

module prism(l, w, h)
{
    polyhedron(
        points=[[0,0,0], [l,0,0], [l,w,0], [0,w,0], [0,w,h], [l,w,h]],
        faces=[[0,1,2,3],[5,4,3,2],[0,4,5,1],[0,3,4],[5,2,1]]
        );
}

module cadding(x, board_height, board_width_b, board_width_s, degrees)
{
    translate([0, -board_width_b, 0]) color("Peru",0.6) rotate([-degrees,0,0])
    {
        cube([x, board_width_b - board_width_s, board_height]);
        translate([0,- board_width_s,0]) prism(x, board_width_s, board_height);
    }
}

module caddings(x, z, board_height = 150, board_width_b = 11, board_width_s = 6, overlap = 25, degrees=3)
{
    panel_uplift = board_height - overlap;
    panels = round(-0.5+z/panel_uplift);
    for(p = [0 : panels-1])
    {
        translate([0,0,panel_uplift * p])
         cadding(x, board_height, board_width_b, board_width_s, degrees);
    }
}

module claddingBackWall(x,z)
{
    translate([x,0,0]) rotate([0,0,180]) caddings(x, z);
}

module claddingLeftSideWall(x,z)
{
    opp = z-shed_front_back;
    adj = x - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    echo("Degrees: ", theta);
    translate([0,x,0]) rotate([0,0,270]) difference()
    {
        caddings(x, z);
      translate([0,-opp/2,z-opp]) rotate([0,-theta,0]) cube([x+10,opp,opp]);
    }
}

module claddingRightSideWall(x,z)
{
    opp = z-shed_front_back;
    adj = x - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    echo("Degrees: ", theta);
    translate([0,0,0]) rotate([0,0,90]) difference()
    {
        caddings(x, z);
        translate([0,-opp/2,z]) rotate([0,theta,0]) cube([x+10,opp,opp]);
    }
}

module claddingFrontWall(x,z, space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h)
{
    translate([0,0,0]) rotate([0,0,0]) difference()
    {
        caddings(x, z);
        translate([space_to_window_w,-100,space_to_window_h]) rotate([0,0,0]) cube([window_w,200,window_h]);
        translate([space_to_window_w*2+window_w,-100,0]) rotate([0,0,0]) cube([door_w,200,door_h]);
    }
}

module frontWallStruts(x,z, space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h, braces)
{
    echo("frontWallStruts(x,z,space_to_window_w, space_to_window_h, window_w, window_h, door_w, braces)", x,z, space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h, braces);
    translate([0,0,0]) verticalStruts(space_to_window_w,space_to_window_h+window_h, braces = braces);
    translate([space_to_window_w,0,0]) verticalStruts(window_w,space_to_window_h, braces = braces, beams=1);
    translate([0,0,space_to_window_h+window_h]) verticalStruts(space_to_window_w/2,z-(space_to_window_h+window_h), braces = braces);
    translate([space_to_window_w/2,0,space_to_window_h+window_h]) verticalStruts(window_w+space_to_window_w,z-(space_to_window_h+window_h), braces = braces, beams=2);
    translate([space_to_window_w+window_w,0,0]) verticalStruts(space_to_window_w,space_to_window_h+window_h, braces = braces);
    if(door_h-(space_to_window_h+window_h>0))  translate([space_to_window_w/2+window_w+space_to_window_w,0,space_to_window_h+window_h]) verticalStruts(space_to_window_w/2,door_h-(space_to_window_h+window_h), braces = braces);
    translate([space_to_window_w/2+window_w+space_to_window_w,0,door_h]) verticalStruts(x-(space_to_window_w/2+window_w+space_to_window_w),z-door_h, braces = braces, beams=2);
    translate([space_to_window_w+window_w+space_to_window_w+door_w,0,0]) verticalStruts(x-(space_to_window_w+window_w+space_to_window_w+door_w),door_h, braces = braces);
}

module roofJoist(y,timber_width=75,timber_length=47)
{
    cubeI([timber_width,y,timber_length]);
}

module roofJoists(x,y,number_x,timber_width=75,timber_length=47)
{
    x_inside = x - timber_length*2 - timber_width;
    x_inside_part = x_inside / number_x;
    for(base_x = [0 : number_x])
       {
        translate([timber_length+(x_inside_part*base_x),0,-timber_length])  roofJoist(y);
       }
}

module roof(x,y,z_front,z_back, panel_slf_w = 1220, panel_slf_l = 2440, panel_slf_t = base_sheet_t)
{
    opp = z_front-z_back;
    adj = y - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    overhang = (panel_slf_l-hyp)/2;
    overhang_flat = cos(theta) * overhang;
    overhang_up = sin(theta) * overhang;

    // Want it to line up with front of timber truct not back
    height_adjust = base_timber * tan(theta);
    echo("overhang", overhang, opp, hyp, theta, height_adjust, overhang_flat, overhang_up);
    translate([-overhang_flat,-overhang_flat,z_front+base_timber+panel_slf_t+height_adjust+overhang_up]) rotate([-theta,0,0])
    {
        shedLowerFloor(x+overhang_flat*2,panel_slf_l);
        translate([overhang,overhang,0]) roofJoists(x,y,7 );
    }
}

module restOfGarden(offset_x=-381, offset_y=+381 + shed_width)
{
    garden_width= 5947.4;
    garden_length_shed_space = 2440;
    translate([offset_x, offset_y,0])
    {
        color("Green") cube([garden_width, 10, 1830]);
        translate([0,-garden_length_shed_space-381,0]) color("Green") cube([10, garden_length_shed_space+381, 1830]);
        translate([garden_width,-garden_length_shed_space,0]) color("Green") cube([10, garden_length_shed_space, 1830]);
    }
    translate([-381,-3507.5-2592.5-381,0]) color("Green") cube([10, +3507.5+2592.5+381, 1830]);
//    translate([garden_width-381,-3507.5-2592.5-381,0]) color("Green") cube([10, +3507.5+2592.5+381, 1830]);

    translate([-381+0.1,-3507.5-381,0]) color("red") cube([3202.5, 3507.5, 400]);
    translate([-381+0.1,-3507.5-2592.5-381,0]) color("red") cube([4727.5,2592.5, 400]);

    }

annimate_step = 1/20;

if($t>annimate_step*1)
    shedBase(shed_length, shed_width, number_x=5,number_y=1, braces=1);

if($t>annimate_step*2)
    translate([0,0,base_timber]) floorMembrane(shed_length, shed_width, thickness = 1);

if($t>annimate_step*3)
    translate([0,0,base_timber+1]) shedLowerFloor(shed_length, shed_width);

if($t>annimate_step*4)
    translate([0,shed_width-timber_construct_h,base_timber+1+base_sheet_t])  backWallStruts(shed_length, shed_front_back, 5);
if($t>annimate_step*5)
    translate([timber_construct_h,timber_construct_h,base_timber+1+base_sheet_t])  sideWallStruts(shed_width-timber_construct_h*2,shed_front_back,2, braces=1);

if($t>annimate_step*6)
    translate([shed_length,timber_construct_h,base_timber+1+base_sheet_t])  sideWallStruts(shed_width-timber_construct_h*2,shed_front_back,2, braces=1);

if($t>annimate_step*7)
    translate([0,0,base_timber+1+base_sheet_t])  frontWallStruts(shed_length,shed_front_height, space_to_window_w=1830/2, space_to_window_h=2030-610, window_w=1830, window_h=610, door_w=870, door_h=2030, braces=0);

if($t>annimate_step*8)
    roof(shed_length, shed_width,shed_front_height,shed_front_back);

if($t>annimate_step*9)
    translate([0,shed_width+0.5,base_timber])
        breatherMembrane(shed_length, shed_front_back);

if($t>annimate_step*10)
    translate([-0.5,0,base_timber])
        breatherMembraneSide(shed_width, shed_front_height);

if($t>annimate_step*11)
    translate([shed_length+3,0,base_timber])
        breatherMembraneSide(shed_width, shed_front_height);

if($t>annimate_step*12)
    translate([-3,0,base_timber])
        breatherMembraneFront(shed_length,shed_front_height, thickness=0.5,  space_to_window_w=1830/2, space_to_window_h=2030-610, window_w=1830, window_h=610, door_w=870, door_h=2030);

//shedBaseSection(shed_length/6,shed_width, braces = 1);
if($t>annimate_step*13)
    translate([0,shed_width+3,base_timber])
        claddingBackWall(shed_length, shed_front_back);

if($t>annimate_step*14)
    translate([-3,0,base_timber])
        claddingLeftSideWall(shed_width, shed_front_height);

if($t>annimate_step*15)
    translate([shed_length+3,0,base_timber])
        claddingRightSideWall(shed_width, shed_front_height);

if($t>annimate_step*16)
    translate([-3,0,base_timber])
        claddingFrontWall(shed_length,shed_front_height,  space_to_window_w=1830/2, space_to_window_h=2030-610, window_w=1830, window_h=610, door_w=870, door_h=2030);

//restOfGarden();

shed_length = 5184;
shed_width = 1829+305/2;
shed_front_height = 2400;
shed_front_back = 2135;
base_timber = 47;
base_sheet_t = 18;

module cubeI(size,center=false)
{
    echo("Dim: ",size);
    cube(size, center=center);
}

module shedBaseSection(x,y,timber_width=75,timber_length=47, braces=0)
{
    echo("shedBaseSection: x,y,timber_width,timber_length, braces ", x,y,timber_width,timber_length, braces);
    echo("http://www.wickes.co.uk/Wickes-Sawn-Kiln-Dried-47X75-x-3000mm-Single/p/107186#tab-DynamicDeliveryWebTab_content");
    cubeI([x,timber_width,timber_length]);
    translate([0,y-timber_width,0]) cubeI([x,timber_width,timber_length]);
    translate([0,timber_width,0]) cubeI([timber_width,y-timber_width*2,timber_length]);
    translate([x-timber_width,timber_width,0]) cubeI([timber_width,y-timber_width*2,timber_length]);
    if(braces > 0)
    {
        middle_y = y - timber_width*2;
        part_y = middle_y/(braces+1);
        for(loop=[1 : braces ])
        {
                translate([timber_width,timber_width/(braces+1) + (loop*part_y),0]) cubeI([x-timber_width*2, timber_width,timber_length]);
        }
    }
}

module shedBase(x,y,number_x,number_y, braces=1)
{
    for(base_y = [0 : number_y-1])
    {
        for(base_x = [0 : number_x-1])
            {
                translate([base_x*(x/number_x),base_y*(y/number_y),0]) shedBaseSection(x/number_x,y/number_y, braces = braces);
            }
    }
}

module floorMembrane(x,y,thickness,color="Black", overlap=10)
{
    echo("x,y,thickness=1,color, overlap=1",x,y,thickness,color, overlap);
    echo("http://www.screwfix.com/p/dmp-damp-proof-membrane-black-1000ga-3-x-4m/50464#product_additional_details_container");
    translate([-overlap,-overlap,0]) color(color, 0.5) cube([x+overlap*2,y+overlap*2, thickness]);
}

module breatherMembrane(x,y, thickness=0.5)
{
    // google timber frame breather membrane
    rotate([90,0,0])  floorMembrane(x,y,thickness=thickness,color="Black", overlap=thickness);
}

module breatherMembraneSide(x,y, thickness=0.5)
{
    // google timber frame breather membrane

    opp = y-shed_front_back;
    adj = x - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    echo("Degrees: ", theta);
    translate([0,0,0]) rotate([90,0,90]) difference()
    {
        floorMembrane(x,y,thickness=thickness,color="Black", overlap=thickness);
        translate([0,y,-opp/2]) rotate([0,0,-theta]) cube([x+10,opp,opp]);
    }
}

//module shedLowerFloor(x,y, panel_slf_w = 607, panel_slf_l =   1829, panel_slf_t =   5.5, panel_min_dimentions = 100)
module shedLowerFloor(x,y, panel_slf_w = 1220, panel_slf_l = 2440, panel_slf_t = base_sheet_t, panel_min_dimentions = 100)
{
//    echo("http://www.wickes.co.uk/Wickes-Non-Structural-Hardwood-Plywood-5-5x607x1829mm/p/111196");
    echo("http://www.wickes.co.uk/Wickes-General-Purpose-OSB3-Board-18x1220x2440mm/p/110517");
    x_panels = round(-0.5+x/panel_slf_w);
    y_panels = round(-0.5+y/panel_slf_l);
    echo(y_panels);
    if(y_panels>0) // Panel is Not longer than width
    {
        for(base_y = [0 : y_panels-1]) //Truncate not round
        {
            for(base_x = [0 : x_panels-1])
            {
                translate([base_x*panel_slf_w,base_y*panel_slf_l,0]) cubeI([panel_slf_w, panel_slf_l,panel_slf_t]);
                if(y-(panel_slf_l*y_panels) > panel_min_dimentions)
                translate([base_x*panel_slf_w,y_panels*panel_slf_l,0]) cubeI([panel_slf_w, y-(panel_slf_l*y_panels),panel_slf_t]);
                }
            if(x-(panel_slf_w*x_panels) > panel_min_dimentions)
                translate([(x_panels)*panel_slf_w,(y_panels-1)*panel_slf_l,0]) cubeI([x-(panel_slf_w*x_panels), panel_slf_l,panel_slf_t]);
            if(y-(panel_slf_l*y_panels) > panel_min_dimentions)
                translate([(x_panels)*panel_slf_w,y_panels*panel_slf_l,0]) cubeI([x-(panel_slf_w*x_panels), y-(panel_slf_l*y_panels),panel_slf_t]);
        }
    }
    else // Panel is longer than width
    {
     for(base_x = [0 : x_panels-1])
     {
        translate([base_x*panel_slf_w,0,0]) cubeI([panel_slf_w, y,panel_slf_t]);
     }
     if(x-(panel_slf_w*x_panels) > panel_min_dimentions)
                translate([(x_panels)*panel_slf_w,0,0]) cubeI([x-(panel_slf_w*x_panels), y,panel_slf_t]);
    }
}

module verticalStruts(x,z,timber_width=47,timber_length=47, braces=0, beams=0)
{
//    echo("shedBaseSection(x,z,timber_width,timber_length, braces",x,z,timber_width,timber_length, braces);
//    echo("Walls - http://www.wickes.co.uk/Wickes-Sawn-Kiln-Dried-47-x-47-x-2400mm-Pack-6/p/107114");
    cubeI([x,timber_width,timber_length]);
    translate([0,0,z-timber_width]) cubeI([x,timber_width,timber_length]);
    translate([0,0,timber_width]) cubeI([timber_width,timber_length,z-timber_width*2]);
    translate([x-timber_width,0,timber_width]) cubeI([timber_width,timber_length,z-timber_width*2]);
    if(braces > 0)
    {
        middle_z = z - timber_width*2;
        part_z = middle_z/(braces+1);
        for(loop=[1 : braces ])
        {
                translate([timber_width,0,timber_width/(braces+1) + (loop*part_z)]) cubeI([x-timber_width*2, timber_width,timber_length]);
        }
    }
    if(beams> 0)
    {
        middle_x = x - timber_length*2;
        part_x = middle_x/(beams+1);
        for(loop=[1 : beams ])
        {
                translate([timber_length/(beams+1) + (loop*part_x),0,timber_width]) cubeI([timber_length, timber_width,z-timber_length*2]);
        }
    }
}

module backWallStruts(x,z,number_x, braces=1)
{
    echo("backWallStruts(x,z,number_x, braces)",x,z,number_x, braces);
        for(base_x = [0 : number_x-1])
            {
                translate([base_x*(x/number_x),0,0]) verticalStruts(x/number_x,z, braces = braces);
            }
}

module sideWallStruts(x,z,number_x, braces=1)
{
    echo("sideWallStruts(x,z,number_x, braces)",x,z,number_x, braces);
    rotate([0,0,90]) backWallStruts(x,z,number_x, braces);
}

module prism(l, w, h)
{
    polyhedron(
        points=[[0,0,0], [l,0,0], [l,w,0], [0,w,0], [0,w,h], [l,w,h]],
        faces=[[0,1,2,3],[5,4,3,2],[0,4,5,1],[0,3,4],[5,2,1]]
        );
}

module cadding(x, board_height, board_width_b, board_width_s, degrees)
{
    translate([0, -board_width_b, 0]) color("Peru",0.6) rotate([-degrees,0,0])
    {
        cube([x, board_width_b - board_width_s, board_height]);
        translate([0,- board_width_s,0]) prism(x, board_width_s, board_height);
    }
}

module caddings(x, z, board_height = 150, board_width_b = 11, board_width_s = 6, overlap = 25, degrees=3)
{
    panel_uplift = board_height - overlap;
    panels = round(-0.5+z/panel_uplift);
    for(p = [0 : panels-1])
    {
        translate([0,0,panel_uplift * p])
         cadding(x, board_height, board_width_b, board_width_s, degrees);
    }
}

module claddingBackWall(x,z)
{
    translate([x,0,0]) rotate([0,0,180]) caddings(x, z);
}

module claddingLeftSideWall(x,z)
{
    opp = z-shed_front_back;
    adj = x - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    echo("Degrees: ", theta);
    translate([0,x,0]) rotate([0,0,270]) difference()
    {
        caddings(x, z);
      translate([0,-opp/2,z-opp]) rotate([0,-theta,0]) cube([x+10,opp,opp]);
    }
}

module claddingRightSideWall(x,z)
{
    opp = z-shed_front_back;
    adj = x - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    echo("Degrees: ", theta);
    translate([0,0,0]) rotate([0,0,90]) difference()
    {
        caddings(x, z);
        translate([0,-opp/2,z]) rotate([0,theta,0]) cube([x+10,opp,opp]);
    }
}

module claddingFrontWall(x,z, space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h)
{
    translate([0,0,0]) rotate([0,0,0]) difference()
    {
        caddings(x, z);
        translate([space_to_window_w,-100,space_to_window_h]) rotate([0,0,0]) cube([window_w,200,window_h]);
        translate([space_to_window_w*2+window_w,-100,0]) rotate([0,0,0]) cube([door_w,200,door_h]);
    }
}

module frontWallStruts(x,z, space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h, braces)
{
    echo("frontWallStruts(x,z,space_to_window_w, space_to_window_h, window_w, window_h, door_w, braces)", x,z, space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h, braces);
    translate([0,0,0]) verticalStruts(space_to_window_w,space_to_window_h+window_h, braces = braces);
    translate([space_to_window_w,0,0]) verticalStruts(window_w,space_to_window_h, braces = braces, beams=1);
    translate([0,0,space_to_window_h+window_h]) verticalStruts(space_to_window_w/2,z-(space_to_window_h+window_h), braces = braces);
    translate([space_to_window_w/2,0,space_to_window_h+window_h]) verticalStruts(window_w+space_to_window_w,z-(space_to_window_h+window_h), braces = braces, beams=2);
    translate([space_to_window_w+window_w,0,0]) verticalStruts(space_to_window_w,space_to_window_h+window_h, braces = braces);
    if(door_h-(space_to_window_h+window_h>0))  translate([space_to_window_w/2+window_w+space_to_window_w,0,space_to_window_h+window_h]) verticalStruts(space_to_window_w/2,door_h-(space_to_window_h+window_h), braces = braces);
    translate([space_to_window_w/2+window_w+space_to_window_w,0,door_h]) verticalStruts(x-(space_to_window_w/2+window_w+space_to_window_w),z-door_h, braces = braces, beams=2);
    translate([space_to_window_w+window_w+space_to_window_w+door_w,0,0]) verticalStruts(x-(space_to_window_w+window_w+space_to_window_w+door_w),door_h, braces = braces);
}

module roofJoist(y,timber_width=75,timber_length=47)
{
    cubeI([timber_width,y,timber_length]);
}

module roofJoists(x,y,number_x,timber_width=75,timber_length=47)
{
    x_inside = x - timber_length*2 - timber_width;
    x_inside_part = x_inside / number_x;
    for(base_x = [0 : number_x])
       {
        translate([timber_length+(x_inside_part*base_x),0,-timber_length])  roofJoist(y);
       }
}

module roof(x,y,z_front,z_back, panel_slf_w = 1220, panel_slf_l = 2440, panel_slf_t = base_sheet_t)
{
    opp = z_front-z_back;
    adj = y - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    overhang = (panel_slf_l-hyp)/2;
    overhang_flat = cos(theta) * overhang;
    overhang_up = sin(theta) * overhang;

    // Want it to line up with front of timber truct not back
    height_adjust = base_timber * tan(theta);
    echo("overhang", overhang, opp, hyp, theta, height_adjust, overhang_flat, overhang_up);
    translate([-overhang_flat,-overhang_flat,z_front+base_timber+panel_slf_t+height_adjust+overhang_up]) rotate([-theta,0,0])
    {
        shedLowerFloor(x+overhang_flat*2,panel_slf_l);
        translate([overhang,overhang,0]) roofJoists(x,y,6 );
    }
}

module restOfGarden(offset_x=-381, offset_y=+381 + shed_width)
{
    garden_width= 5947.4;
    garden_length_shed_space = 2440;
    translate([offset_x, offset_y,0])
    {
        color("Green") cube([garden_width, 10, 1830]);
        translate([0,-garden_length_shed_space-381,0]) color("Green") cube([10, garden_length_shed_space+381, 1830]);
        translate([garden_width,-garden_length_shed_space,0]) color("Green") cube([10, garden_length_shed_space, 1830]);
    }
    translate([-381,-3507.5-2592.5-381,0]) color("Green") cube([10, +3507.5+2592.5+381, 1830]);
//    translate([garden_width-381,-3507.5-2592.5-381,0]) color("Green") cube([10, +3507.5+2592.5+381, 1830]);

    translate([-381+0.1,-3507.5-381,0]) color("red") cube([3202.5, 3507.5, 400]);
    translate([-381+0.1,-3507.5-2592.5-381,0]) color("red") cube([4727.5,2592.5, 400]);

    }

if($t>0.05)
    shedBase(shed_length, shed_width, number_x=5,number_y=1, braces=1);

if($t>0.10)
    translate([0,0,base_timber]) floorMembrane(shed_length, shed_width, thickness = 1);

if($t>0.15)
    translate([0,0,base_timber+1]) shedLowerFloor(shed_length, shed_width);

if($t>0.20)
    translate([0,shed_width-base_timber,base_timber+1+base_sheet_t])  backWallStruts(shed_length, shed_front_back, 5);
if($t>0.25)
    translate([base_timber,base_timber,base_timber+1+base_sheet_t])  sideWallStruts(shed_width-base_timber*2,shed_front_back,2, braces=1);

if($t>0.30)
    translate([shed_length,base_timber,base_timber+1+base_sheet_t])  sideWallStruts(shed_width-base_timber*2,shed_front_back,2, braces=1);

if($t>0.35)
    translate([0,0,base_timber+1+base_sheet_t])  frontWallStruts(shed_length,shed_front_height, space_to_window_w=1830/2, space_to_window_h=2030-610, window_w=1830, window_h=610, door_w=870, door_h=2030, braces=0);

if($t>0.40)
    roof(shed_length, shed_width,shed_front_height,shed_front_back);

if($t>0.45)
    translate([0,shed_width+0.5,base_timber])
        breatherMembrane(shed_length, shed_front_back);

if($t>0.50)
    translate([-0.5,0,base_timber])
        breatherMembraneSide(shed_width, shed_front_height);

//shedBaseSection(shed_length/6,shed_width, braces = 1);
if($t>0.65)
    translate([0,shed_width+3,base_timber])
        claddingBackWall(shed_length, shed_front_back);

if($t>0.70)
    translate([-3,0,base_timber])
        claddingLeftSideWall(shed_width, shed_front_height);

if($t>0.75)
    translate([shed_length+3,0,base_timber])
        claddingRightSideWall(shed_width, shed_front_height);

if($t>0.80)
    translate([-3,0,base_timber])
        claddingFrontWall(shed_length,shed_front_height,  space_to_window_w=1830/2, space_to_window_h=2030-610, window_w=1830, window_h=610, door_w=870, door_h=2030);

//restOfGarden();


body: top_surface correctoin

body: top_surface correctoin

include <constants.scad>;
HEIGHT_BODY = 44.5;
DIAMETER_BODY = 10.4;
BORDER_RADIUS_BODY = 0.2;
HEIGHT_NIPPLE = 0.8;

module top_surface()
{
    position_z = -(HEIGHT_NIPPLE + BORDER_RADIUS_BODY);
    position = [0,0,position_z];

    correction_diameter_base = (2 * BORDER_RADIUS_BODY);
    diameter_base = DIAMETER_BODY - correction_diameter_base;

    translate(position)
    cylinder(
        h = BORDER_RADIUS_BODY,
        d = diameter_base,
        $fn = FINE);
}

module body()
{
    top_surface();

//Body top shoulder
translate([0,0,-(HEIGHT_NIPPLE + BORDER_RADIUS_BODY)])
    rotate_extrude(convexity = CONVEXITY, $fn = FINE)
    translate([(DIAMETER_BODY/2)-BORDER_RADIUS_BODY, 0, 0])
        circle(r = BORDER_RADIUS_BODY, $fn = FINE);

//Main body cylinder
translate([0,0,-(HEIGHT_BODY - BORDER_RADIUS_BODY)])
    cylinder(
        h = (HEIGHT_BODY - (HEIGHT_NIPPLE + (2* BORDER_RADIUS_BODY))),
        d = DIAMETER_BODY,
        $fn = FINE);

//Body bottom shoulder
translate([0,0,-(HEIGHT_BODY - BORDER_RADIUS_BODY)])
    rotate_extrude(convexity = CONVEXITY, $fn = FINE)
    translate([(DIAMETER_BODY/2)-BORDER_RADIUS_BODY, 0, 0])
        circle(r = BORDER_RADIUS_BODY, $fn = FINE);

//Bottom face of body
translate([0,0,-(HEIGHT_BODY)])
    cylinder(
        h = BORDER_RADIUS_BODY,
        d = (DIAMETER_BODY - (2 * BORDER_RADIUS_BODY)),
        $fn = FINE);
}

body();

include <constants.scad>;
HEIGHT_BODY = 44.5;
DIAMETER_BODY = 10.4;
BORDER_RADIUS_BODY = 0.2;
HEIGHT_NIPPLE = 0.8;

module top_surface()
{
    position_z = -(HEIGHT_NIPPLE + BORDER_RADIUS_BODY);
    position = [0,0,position_z];
    translate(position)
    cylinder(
        h = BORDER_RADIUS_BODY,
        d = (DIAMETER_BODY - (2 * BORDER_RADIUS_BODY)),
        $fn = FINE);
}

module body()
{
    top_surface();

//Body top shoulder
translate([0,0,-(HEIGHT_NIPPLE + BORDER_RADIUS_BODY)])
    rotate_extrude(convexity = CONVEXITY, $fn = FINE)
    translate([(DIAMETER_BODY/2)-BORDER_RADIUS_BODY, 0, 0])
        circle(r = BORDER_RADIUS_BODY, $fn = FINE);

//Main body cylinder
translate([0,0,-(HEIGHT_BODY - BORDER_RADIUS_BODY)])
    cylinder(
        h = (HEIGHT_BODY - (HEIGHT_NIPPLE + (2* BORDER_RADIUS_BODY))),
        d = DIAMETER_BODY,
        $fn = FINE);

//Body bottom shoulder
translate([0,0,-(HEIGHT_BODY - BORDER_RADIUS_BODY)])
    rotate_extrude(convexity = CONVEXITY, $fn = FINE)
    translate([(DIAMETER_BODY/2)-BORDER_RADIUS_BODY, 0, 0])
        circle(r = BORDER_RADIUS_BODY, $fn = FINE);

//Bottom face of body
translate([0,0,-(HEIGHT_BODY)])
    cylinder(
        h = BORDER_RADIUS_BODY,
        d = (DIAMETER_BODY - (2 * BORDER_RADIUS_BODY)),
        $fn = FINE);
}

body();


wanhao-i3-z-stop: handle side clamp offset more gracefully

include <../libs/trig.scad>;

// enlarged to account for shrink
g3mm = 3.45;
g3mmnut = 5.85;
g2mm = 2.0;
gNutChamfer = 0.5;

gMicroswitchHoleSpacing = 6.0;
gSideClampHole1 = 0;
gSideClampHole2 = 10;

gTopClampY1 = 15;
gTopClampY2 = 30;
gClampOffset = 10;
gSideClampOffset = 0;

module NutTrap(x,h=100) {
    cylinder(d=x/0.866,h=h,$fn=6);
    translate([0,0,-0.01])
        cylinder(d1=(x+gNutChamfer)/0.866,d2=x/0.866,h=gNutChamfer,$fn=6);
}

/* cylinder_wall_thick should be a small integer *nozzle_dia */
module NutTrapSupport(d,h,cylinder_wall_thick=0.7,cylinder_wall_offset=0.1) {
    cylinder(d=d+cylinder_wall_offset*2,h=h,$fn=16);
}

module Fillet(r,h=100) {
    difference() {
        cube([r,r,h]);
        translate([0,0,-1]) cylinder(r=r,h=h+2);
    }
}

/* Side clamp, in two parts */

module SideBody() {
    difference() {
        translate([0,-4,0]) cube([22,24,5+gSideClampOffset]);
        if(gSideClampOffset > 0) {
            translate([1,-4.01,5.01]) cube([22,16,10]);
            translate([0.5,0.5,5.01]) linear_extrude(height=10, convexity=3) SideClampOutline();
        }
        translate([-1,-5,3.5]) cube([11,27,5+gSideClampOffset]);
        translate([14,17,-1]) cylinder(d=g2mm,h=100,$fn=32);
        translate([14+gMicroswitchHoleSpacing,17,-1]) cylinder(d=g2mm,h=100,$fn=32);
        translate([8,gSideClampHole1,-1]) cylinder(d=g3mm,h=100,$fn=32);
        translate([8,gSideClampHole2,-1]) cylinder(d=g3mm,h=100,$fn=32);
    }
}

gSidePos1 = [8,18];
gSidePos2 = [11,4];
gSideCutoutRad = 25;

module SideClampOutline() {
    difference() {
        hull() for(c=[[4,-2],[11,-2],[4,18],gSidePos1,gSidePos2])
            translate(c) circle(r=2,$fn=32);
        translate([0,0,-1])
            translate(CircleCircleIntersection(gSidePos1, gSidePos2, 2, gSideCutoutRad))
            circle(r=gSideCutoutRad,$fn=256);
    }
}

module SideClamp() {
    difference() {
        linear_extrude(height=5, convexity=3) SideClampOutline();
        //translate(gSidePos1) cylinder(r=2,h=10);
        //translate(gSidePos2) cylinder(r=2,h=10);
        translate([8,gSideClampHole1,-1]) union() {
            cylinder(d=g3mm,h=100,$fn=32);
            translate([0,0,6.1]) scale([1,1,-1]) NutTrap(g3mmnut,3);
        }
        translate([8,gSideClampHole2,-1]) {
            cylinder(d=g3mm,h=100,$fn=32);
            translate([0,0,6.1]) scale([1,1,-1]) NutTrap(g3mmnut,3);
        }
    }
}

/* Top clamp, in two parts */

module TopBody() {
    difference() {
        union() {
            translate([-1,0,0]) cube([11,35,12]);
            /* thing adjustment screw goes on */
            hull() for(x=[-9,0])
                for(y=[1,9])
                    translate([x,y]) cylinder(r=1,h=12);
            translate([-2.99,11.99,0]) rotate([0,0,-90]) Fillet(2,12);
        }
        hull() {
            for(x=[5,10])
                for(y=[10,50])
                    translate([x,y,3])
                    cylinder(r=2,h=100);
        }
        hull() {
            for(x=[5+1.7,10])
                for(y=[10+1.7,50])
                    translate([x,y,-1])
                    cylinder(r=2,h=100);
        }
        /* adjustment screw */
        translate([-5,5,0]) {
            NutTrap(g3mmnut,3);
            cylinder(d=g3mm,h=200);
        }
        /* notch for frame */
        hull() {
            for(x=[8,20])
            translate([x,0,-1]) cylinder(r=2,h=100);
        }
        /* clamp holes */
        for(y=[gTopClampY1,gTopClampY2])
            translate([-10,y,6])
            rotate([0,90,0]) cylinder(d=g3mm,h=100);
    }
    /* adjustment screw support */
    translate([-5,5,0]) NutTrapSupport(g3mm,3);
}

module TopClamp() {
    difference() {
        intersection() {
            cube([12,25,6]);
            hull() {
                translate([0,2,4]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,50,4]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,50,-50]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,2,-50]) rotate([0,90,0]) cylinder(r=2,h=100);
            }
        }
        /* clamp holes */
        for(y=[gTopClampY1,gTopClampY2])
            translate([6,y-gClampOffset,0]) {
                cylinder(d=g3mm,h=100);
                NutTrap(g3mmnut,3);
            }
    }
    /* clamp holes support */
    for(y=[gTopClampY1,gTopClampY2])
        translate([6,y-gClampOffset,0])
            NutTrapSupport(g3mm,3);
}

TopBody($fn=32);

/* to visualize together */
/* translate([11,gClampOffset,0]) rotate([0,-90,0]) Clamper($fn=32); */
/* for printing */
translate([7,gClampOffset+2,0]) TopClamp($fn=32);

translate([-25,15,0]) SideBody();
/* to visualise together  */
/* translate([-25,15,6+gSideClampOffset]) SideClamp(); */
/* for printing */
translate([-15,-3,0]) rotate([0,0,90]) SideClamp();

include <../libs/trig.scad>;

// enlarged to account for shrink
g3mm = 3.45;
g3mmnut = 5.85;
g2mm = 2.0;
gNutChamfer = 0.5;

gMicroswitchHoleSpacing = 6.0;
gSideClampHole1 = 0;
gSideClampHole2 = 10;

gTopClampY1 = 15;
gTopClampY2 = 30;
gClampOffset = 10;
gSideClampOffset = 0;

module NutTrap(x,h=100) {
    cylinder(d=x/0.866,h=h,$fn=6);
    translate([0,0,-0.01])
        cylinder(d1=(x+gNutChamfer)/0.866,d2=x/0.866,h=gNutChamfer,$fn=6);
}

/* cylinder_wall_thick should be a small integer *nozzle_dia */
module NutTrapSupport(d,h,cylinder_wall_thick=0.7,cylinder_wall_offset=0.1) {
    cylinder(d=d+cylinder_wall_offset*2,h=h,$fn=16);
}

module Fillet(r,h=100) {
    difference() {
        cube([r,r,h]);
        translate([0,0,-1]) cylinder(r=r,h=h+2);
    }
}

/* Side clamp, in two parts */

module SideBody() {
    difference() {
        translate([0,-4,0]) cube([22,24,5+gSideClampOffset]);
        translate([-1,-5,3.5]) cube([11,27,5+gSideClampOffset]);
        translate([14,17,-1]) cylinder(d=g2mm,h=100,$fn=32);
        translate([14+gMicroswitchHoleSpacing,17,-1]) cylinder(d=g2mm,h=100,$fn=32);
        translate([8,gSideClampHole1,-1]) cylinder(d=g3mm,h=100,$fn=32);
        translate([8,gSideClampHole2,-1]) cylinder(d=g3mm,h=100,$fn=32);
    }
}

gSidePos1 = [8,18];
gSidePos2 = [11,4];
gSideCutoutRad = 25;

module SideClamp() {
    difference() {
        hull() for(c=[[4,-2],[11,-2],[4,18],gSidePos1,gSidePos2])
            translate(c) cylinder(r=2,h=5,$fn=32);
        translate([0,0,-1])
            translate(CircleCircleIntersection(gSidePos1, gSidePos2, 2, gSideCutoutRad))
            cylinder(r=gSideCutoutRad,h=10,$fn=100);
        //translate(gSidePos1) cylinder(r=2,h=10);
        //translate(gSidePos2) cylinder(r=2,h=10);
        translate([8,gSideClampHole1,-1]) union() {
            cylinder(d=g3mm,h=100,$fn=32);
            translate([0,0,6.1]) scale([1,1,-1]) NutTrap(g3mmnut,3);
        }
        translate([8,gSideClampHole2,-1]) {
            cylinder(d=g3mm,h=100,$fn=32);
            translate([0,0,6.1]) scale([1,1,-1]) NutTrap(g3mmnut,3);
        }
    }
}

/* Top clamp, in two parts */

module TopBody() {
    difference() {
        union() {
            translate([-1,0,0]) cube([11,35,12]);
            /* thing adjustment screw goes on */
            hull() for(x=[-9,0])
                for(y=[1,9])
                    translate([x,y]) cylinder(r=1,h=12);
            translate([-2.99,11.99,0]) rotate([0,0,-90]) Fillet(2,12);
        }
        hull() {
            for(x=[5,10])
                for(y=[10,50])
                    translate([x,y,3])
                    cylinder(r=2,h=100);
        }
        hull() {
            for(x=[5+1.7,10])
                for(y=[10+1.7,50])
                    translate([x,y,-1])
                    cylinder(r=2,h=100);
        }
        /* adjustment screw */
        translate([-5,5,0]) {
            NutTrap(g3mmnut,3);
            cylinder(d=g3mm,h=200);
        }
        /* notch for frame */
        hull() {
            for(x=[8,20])
            translate([x,0,-1]) cylinder(r=2,h=100);
        }
        /* clamp holes */
        for(y=[gTopClampY1,gTopClampY2])
            translate([-10,y,6])
            rotate([0,90,0]) cylinder(d=g3mm,h=100);
    }
    /* adjustment screw support */
    translate([-5,5,0]) NutTrapSupport(g3mm,3);
}

module TopClamp() {
    difference() {
        intersection() {
            cube([12,25,6]);
            hull() {
                translate([0,2,4]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,50,4]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,50,-50]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,2,-50]) rotate([0,90,0]) cylinder(r=2,h=100);
            }
        }
        /* clamp holes */
        for(y=[gTopClampY1,gTopClampY2])
            translate([6,y-gClampOffset,0]) {
                cylinder(d=g3mm,h=100);
                NutTrap(g3mmnut,3);
            }
    }
    /* clamp holes support */
    for(y=[gTopClampY1,gTopClampY2])
        translate([6,y-gClampOffset,0])
            NutTrapSupport(g3mm,3);
}

TopBody($fn=32);

/* to visualize together */
/* translate([11,gClampOffset,0]) rotate([0,-90,0]) Clamper($fn=32); */
/* for printing */
translate([7,gClampOffset+2,0]) TopClamp($fn=32);

translate([-25,15,0]) SideBody();
/* to visualise together  */
/* translate([-25,15,5]) SideClamp(); */
/* for printing */
translate([-15,-3,0]) rotate([0,0,90]) SideClamp();


wall height is now a parameter, too

wall height is now a parameter, too

eps = 0.01;
wall = 2;
wall_h = 4;
spacing = 1;

module model_import(file)
{
  offset(eps)
    import(file);
}

module shape_placeholder()
{
  linear_extrude(2*wall)
    model_import("random_shape.svg");
}

module model_slot_base(name)
{
  module extended_base(r)
  {
    minkowski()
    {
      model_import(name);
      circle(r);
    }
  }

  module frame(wall)
  {
    difference()
    {
      extended_base(spacing + wall/2 + 0.5);
      extended_base(spacing + wall/2);
    }
  }

  module cut_in_frame()
  {
    difference()
    {
      // model
      frame(wall);
      // side wall cuts
      children();
    }
  }

  cut_in_frame()
    children();
}

module model_slot(name)
{
  intersection()
  {
    minkowski()
    {
      linear_extrude(wall_h)
        model_slot_base(name)
          children();
      sphere(r=wall/2);
    }
    // cut-off for the bottom roundings
    // we're only interested in the top of the model
    translate([-50, -50, 0])
      cube(300*[1,1,1]);
  }
}

%shape_placeholder();
model_slot("random_shape.svg")
{
  // some location(s) that shall be removed from the overall shape:
  // bottom
  translate([40, -10, 0])
    square([60, 20]);
  // top
  translate([60, 110, 0])
    square([50, 20]);
}

eps = 0.01;
wall = 2;
spacing = 1;

module model_import(file)
{
  offset(eps)
    import(file);
}

module shape_placeholder()
{
  linear_extrude(2*wall)
    model_import("random_shape.svg");
}

module model_slot_base(name)
{
  module extended_base(r)
  {
    minkowski()
    {
      model_import(name);
      circle(r);
    }
  }

  module frame(wall)
  {
    difference()
    {
      extended_base(spacing + wall/2 + 0.5);
      extended_base(spacing + wall/2);
    }
  }

  module cut_in_frame()
  {
    difference()
    {
      // model
      frame(wall);
      // side wall cuts
      children();
    }
  }

  cut_in_frame()
    children();
}

module model_slot(name)
{
  intersection()
  {
    minkowski()
    {
      linear_extrude(2.7)
        model_slot_base(name)
          children();
      sphere(r=wall/2);
    }
    // cut-off for the bottom roundings
    translate([-50, -50, 0])
      cube(300*[1,1,1]);
  }
}

%shape_placeholder();
model_slot("random_shape.svg")
{
  // some location(s) that shall be removed from the overall shape:
  // bottom
  translate([40, -10, 0])
    square([60, 20]);
  // top
  translate([60, 110, 0])
    square([50, 20]);
}


misc: use fallback func

misc: use fallback func

use <scad-utils/linalg.scad>
use <scad-utils/lists.scad>

function posvec(path_vec) = [for(v=path_vec) translation_part(v)];
function posvec_x(path_vec) = [for(v=path_vec) translation_part(v)[0]];
function posvec_y(path_vec) = [for(v=path_vec) translation_part(v)[1]];
function posvec_z(path_vec) = [for(v=path_vec) translation_part(v)[2]];

function vec_i(v3,i) = [for(v=v3) v[i]];
function vec_0(v3) = vec_i(v3,0);
function vec_1(v3) = vec_i(v3,1);
function vec_2(v3) = vec_i(v3,2);

function vec_add(vec,v) = [for(vv=vec) vv+v];

function v_itrlen(vec) = [0:1:len(vec)-1];

function range1(v1) = [min(v1), max(v1)];
function range3(v3) = [range1(vec_0(v3)), range1(vec_1(v3)), range1(vec_2(v3))];
function bbox(r) = [ [r[0][0],r[1][0],r[2][0]], [r[0][1],r[1][1],r[2][1]] ];
function transform_pp(vec_m, t_pre, t_post) = [for(m=vec_m) (t_pre*m)*t_post];
function transform_pre(vec_m, t) = [for(m=vec_m) t*m];
function transform_post(vec_m, t) = [for(m=vec_m) m*t];

function clamp(v, v1, v2) = min(max(v,v1),v2);

// from the start (or s'th element) to the e'th element - remember elements are zero based
function v_sum(v,e=undef,start=0) =
let(e_= fallback(e, len(v)-1))
(e==start ? v[e] : v[e_] + v_sum(v,e_-1,start));

function v_abs(v, start=0) = [for(i=[start:1:len(v)-1]) abs(v[i])];
function v_sign(v, start=0) = [for(i=[start:1:len(v)-1]) sign(v[i])];
function v_max(v, m, start=0) = [for(i=[start:1:len(v)-1]) max(v[i],m)];
function v_min(v, m, start=0) = [for(i=[start:1:len(v)-1]) min(v[i],m)];
function v_clamp(v, v1, v2, start=0) = [for(i=[start:1:len(v)-1]) clamp(v[i],v1,v2)];

// cumulative sum of vector [1,2,3] = [1,3,6]
function v_cumsum(v, start=0) = [for(i=[start:1:len(v)-1]) v_sum(v,i)];

// filter/remove a val from a vec
function filter(vec,val=undef) = [for(v=vec) if(v!=val) v];

function vec_pair_double_transform_post(vec,t1,t2)=
    flatten(
        [for(v=vec)
            [transform_post(v,t1),transform_post(v,t2)]
        ]);

function vec_pair_double(vec)=flatten([for(v=vec) [v,v] ]);

/** Calculates length of hypotenuse according to pythagoras */
function pythag_hyp(a, b)=sqrt(a*a+b*b);
function pythag_leg(b, c)=sqrt(c*c-b*b);

//-- Calculate the module of a vector
function v_mod(v) = (sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]));

//-- Calculate the cros product of two vectors
function v_cross(u,v) = [
  u[1]*v[2] - v[1]*u[2],
  -(u[0]*v[2] - v[0]*u[2]) ,
  u[0]*v[1] - v[0]*u[1]];

//-- Calculate the dot product of two vectors
function v_dot(u,v) = u[0]*v[0]+u[1]*v[1]+u[2]*v[2];

//-- Return the unit vector of a vector
function v_unitv(v) = v/v_mod(v);

//-- Return the angle between two vectores
function v_anglev(u,v) = acos( v_dot(u,v) / (v_mod(u)*v_mod(v)) );

function _orient_angles(zaxis)=
[-asin(zaxis.y / norm(zaxis)),
    atan2(zaxis.x, zaxis.z),
    0];

//matrix rotation functions
function _rotate_x_matrix(a)=
[[1,0,0,0],
    [0,cos(a),-sin(a),0],
    [0,sin(a),cos(a),0],
    [0,0,0,1]];

function _rotate_y_matrix(a)=
[[cos(a),0,sin(a),0],
    [0,1,0,0],
    [-sin(a),0,cos(a),0],
    [0,0,0,1]];

function _rotate_z_matrix(a)=
[[cos(a),-sin(a),0,0],
    [sin(a),cos(a),0,0],
    [0,0,1,0],
    [0,0,0,1]];

function _rotate_matrix(a)=_rotate_z_matrix(a.z)*_rotate_y_matrix(a.y)*_rotate_x_matrix(a.x);

//hadamard product (aka "component-wise" product) for vectors
function hadamard(v1,v2) = [v1.x*v2.x, v1.y*v2.y, v1.z*v2.z];

// search in a dictionary (vector w/key-value pairs) and replace the value for a given key
function dict_replace(dict, key, newvalue)=[
        for(kv=dict)
        kv[0] == key ?
            [key, newvalue]
            :
            kv
        ];

function dict_replace_multiple(dict, newvaluesdict)=[
    for(kv_old=dict)
    let(r = search(kv_old[0], newvaluesdict, num_returns_per_match=0, index_col_num=0))
    r==[]?kv_old:newvaluesdict[r[0]]
    ];

function sinh(x) = (1 - pow(e, -2 * x)) / (2 * pow(e, -x));
function cosh(x) = (1 + pow(e, -2 * x)) / (2 * pow(e, -x));
function tanh(x) = sinh(x) / cosh(x);
function cot(x) = 1 / tan(x);

function factorial(n) = n == 0 ? 1 : factorial(n - 1) * n;

if(false)
{
    vec=[ 10, 20, 30, 40 ];
    echo("v_sum=", v_sum(vec,2,1)); // is 20+30=50
    echo("v_sum=", v_sum(vec));
    echo("v_cumsum=", v_cumsum(vec));
}

// FUNCTION: is_String(x)
//   Returns true if x is a string, false otherwise.
function is_string(x) =
	x == undef || len(x) == undef
		? false // if undef, a boolean or a number
		: len(str(x,x)) == len(x)*2; // if an array, this is false

// FUNCTION: is_array(x)
//   Returns true if x is an array, false otherwise.
function is_array(x) = is_string(x) ? false : len(x) != undef;

function identity(d)        = d == 0 ? 1 : [for(y=[1:d]) [for(x=[1:d]) x == y ? 1 : 0] ];
function unit_vector(v)     = let(x=v[0], y=v[1], z=v[2]) [x/norm(v), y/norm(v), z/norm(v)];
function skew_symmetric(v)  = let(x=v[0], y=v[1], z=v[2]) [[0, -z, y], [z, 0, -x], [-y, x, 0]];
function tensor_product1(u) = let(x=u[0], y=u[1], z=u[2]) [[x*x, x*y, x*z], [x*y, y*y, y*z], [x*z, y*z, z*z]];
function v_rotate(a, v)
    = is_array(a)
? let(rx=a[0], ry=a[1], rz=a[2])
    [[1, 0, 0],              [0, cos(rx), -sin(rx)], [0, sin(rx), cos(rx)]]
    * [[cos(ry), 0, sin(ry)],  [0, 1, 0],              [-sin(ry), 0, cos(ry)]]
    * [[cos(rz), -sin(rz), 0], [sin(rz), cos(rz), 0],  [0, 0, 1]]
    : let(uv=unit_vector(v))
    cos(a)*identity(3) + sin(a)*skew_symmetric(uv) + (1 - cos(a))*tensor_product1(uv);

 /*echo(rotate(90, [1,0,0]) * [1, 0, 0]);*/
 /*echo(rotate(90, [1,0,0]) * [0, 1, 0]);*/
 /*echo(rotate(90, [1,0,0]) * [0, 0, 1]);*/

function lerp(v0, v1, t) =  (1-t)*v0 + t*v1;

// echo(fallback(undef,1));
function fallback(a, b) = a==undef?b:a;

// echo(fallback(undef,[undef, 1]));
function v_fallback(a,v,i=0) = (a!=undef || i > len(v)-1) ? a : v_fallback(v[i],v,i+1);

use <scad-utils/linalg.scad>
use <scad-utils/lists.scad>

function posvec(path_vec) = [for(v=path_vec) translation_part(v)];
function posvec_x(path_vec) = [for(v=path_vec) translation_part(v)[0]];
function posvec_y(path_vec) = [for(v=path_vec) translation_part(v)[1]];
function posvec_z(path_vec) = [for(v=path_vec) translation_part(v)[2]];

function vec_i(v3,i) = [for(v=v3) v[i]];
function vec_0(v3) = vec_i(v3,0);
function vec_1(v3) = vec_i(v3,1);
function vec_2(v3) = vec_i(v3,2);

function vec_add(vec,v) = [for(vv=vec) vv+v];

function v_itrlen(vec) = [0:1:len(vec)-1];

function range1(v1) = [min(v1), max(v1)];
function range3(v3) = [range1(vec_0(v3)), range1(vec_1(v3)), range1(vec_2(v3))];
function bbox(r) = [ [r[0][0],r[1][0],r[2][0]], [r[0][1],r[1][1],r[2][1]] ];
function transform_pp(vec_m, t_pre, t_post) = [for(m=vec_m) (t_pre*m)*t_post];
function transform_pre(vec_m, t) = [for(m=vec_m) t*m];
function transform_post(vec_m, t) = [for(m=vec_m) m*t];

function clamp(v, v1, v2) = min(max(v,v1),v2);

// from the start (or s'th element) to the e'th element - remember elements are zero based
function v_sum(v,e=undef,start=0) =
let(e_= e==undef ? len(v)-1 : e)
(e==start ? v[e] : v[e_] + v_sum(v,e_-1,start));

function v_abs(v, start=0) = [for(i=[start:1:len(v)-1]) abs(v[i])];
function v_sign(v, start=0) = [for(i=[start:1:len(v)-1]) sign(v[i])];
function v_max(v, m, start=0) = [for(i=[start:1:len(v)-1]) max(v[i],m)];
function v_min(v, m, start=0) = [for(i=[start:1:len(v)-1]) min(v[i],m)];
function v_clamp(v, v1, v2, start=0) = [for(i=[start:1:len(v)-1]) clamp(v[i],v1,v2)];

// cumulative sum of vector [1,2,3] = [1,3,6]
function v_cumsum(v, start=0) = [for(i=[start:1:len(v)-1]) v_sum(v,i)];

// filter/remove a val from a vec
function filter(vec,val=undef) = [for(v=vec) if(v!=val) v];

function vec_pair_double_transform_post(vec,t1,t2)=
    flatten(
        [for(v=vec)
            [transform_post(v,t1),transform_post(v,t2)]
        ]);

function vec_pair_double(vec)=flatten([for(v=vec) [v,v] ]);

/** Calculates length of hypotenuse according to pythagoras */
function pythag_hyp(a, b)=sqrt(a*a+b*b);
function pythag_leg(b, c)=sqrt(c*c-b*b);

//-- Calculate the module of a vector
function v_mod(v) = (sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]));

//-- Calculate the cros product of two vectors
function v_cross(u,v) = [
  u[1]*v[2] - v[1]*u[2],
  -(u[0]*v[2] - v[0]*u[2]) ,
  u[0]*v[1] - v[0]*u[1]];

//-- Calculate the dot product of two vectors
function v_dot(u,v) = u[0]*v[0]+u[1]*v[1]+u[2]*v[2];

//-- Return the unit vector of a vector
function v_unitv(v) = v/v_mod(v);

//-- Return the angle between two vectores
function v_anglev(u,v) = acos( v_dot(u,v) / (v_mod(u)*v_mod(v)) );

function _orient_angles(zaxis)=
[-asin(zaxis.y / norm(zaxis)),
    atan2(zaxis.x, zaxis.z),
    0];

//matrix rotation functions
function _rotate_x_matrix(a)=
[[1,0,0,0],
    [0,cos(a),-sin(a),0],
    [0,sin(a),cos(a),0],
    [0,0,0,1]];

function _rotate_y_matrix(a)=
[[cos(a),0,sin(a),0],
    [0,1,0,0],
    [-sin(a),0,cos(a),0],
    [0,0,0,1]];

function _rotate_z_matrix(a)=
[[cos(a),-sin(a),0,0],
    [sin(a),cos(a),0,0],
    [0,0,1,0],
    [0,0,0,1]];

function _rotate_matrix(a)=_rotate_z_matrix(a.z)*_rotate_y_matrix(a.y)*_rotate_x_matrix(a.x);

//hadamard product (aka "component-wise" product) for vectors
function hadamard(v1,v2) = [v1.x*v2.x, v1.y*v2.y, v1.z*v2.z];

// search in a dictionary (vector w/key-value pairs) and replace the value for a given key
function dict_replace(dict, key, newvalue)=[
        for(kv=dict)
        kv[0] == key ?
            [key, newvalue]
            :
            kv
        ];

function dict_replace_multiple(dict, newvaluesdict)=[
    for(kv_old=dict)
    let(r = search(kv_old[0], newvaluesdict, num_returns_per_match=0, index_col_num=0))
    r==[]?kv_old:newvaluesdict[r[0]]
    ];

function sinh(x) = (1 - pow(e, -2 * x)) / (2 * pow(e, -x));
function cosh(x) = (1 + pow(e, -2 * x)) / (2 * pow(e, -x));
function tanh(x) = sinh(x) / cosh(x);
function cot(x) = 1 / tan(x);

function factorial(n) = n == 0 ? 1 : factorial(n - 1) * n;

if(false)
{
    vec=[ 10, 20, 30, 40 ];
    echo("v_sum=", v_sum(vec,2,1)); // is 20+30=50
    echo("v_sum=", v_sum(vec));
    echo("v_cumsum=", v_cumsum(vec));
}

// FUNCTION: is_String(x)
//   Returns true if x is a string, false otherwise.
function is_string(x) =
	x == undef || len(x) == undef
		? false // if undef, a boolean or a number
		: len(str(x,x)) == len(x)*2; // if an array, this is false

// FUNCTION: is_array(x)
//   Returns true if x is an array, false otherwise.
function is_array(x) = is_string(x) ? false : len(x) != undef;

function identity(d)        = d == 0 ? 1 : [for(y=[1:d]) [for(x=[1:d]) x == y ? 1 : 0] ];
function unit_vector(v)     = let(x=v[0], y=v[1], z=v[2]) [x/norm(v), y/norm(v), z/norm(v)];
function skew_symmetric(v)  = let(x=v[0], y=v[1], z=v[2]) [[0, -z, y], [z, 0, -x], [-y, x, 0]];
function tensor_product1(u) = let(x=u[0], y=u[1], z=u[2]) [[x*x, x*y, x*z], [x*y, y*y, y*z], [x*z, y*z, z*z]];
function v_rotate(a, v)
    = is_array(a)
? let(rx=a[0], ry=a[1], rz=a[2])
    [[1, 0, 0],              [0, cos(rx), -sin(rx)], [0, sin(rx), cos(rx)]]
    * [[cos(ry), 0, sin(ry)],  [0, 1, 0],              [-sin(ry), 0, cos(ry)]]
    * [[cos(rz), -sin(rz), 0], [sin(rz), cos(rz), 0],  [0, 0, 1]]
    : let(uv=unit_vector(v))
    cos(a)*identity(3) + sin(a)*skew_symmetric(uv) + (1 - cos(a))*tensor_product1(uv);

 /*echo(rotate(90, [1,0,0]) * [1, 0, 0]);*/
 /*echo(rotate(90, [1,0,0]) * [0, 1, 0]);*/
 /*echo(rotate(90, [1,0,0]) * [0, 0, 1]);*/

function lerp(v0, v1, t) =  (1-t)*v0 + t*v1;

// echo(fallback(undef,1));
function fallback(a, b) = a==undef?b:a;

// echo(fallback(undef,[undef, 1]));
function v_fallback(a,v,i=0) = (a!=undef || i > len(v)-1) ? a : v_fallback(v[i],v,i+1);


empty model

empty model

error: pathspec 'chair_repairs/side_arm_support.scad' did not match any file(s) known to git


Added "drawing" of scintillator backplanes

These aluminum backplanes are used to mount the test-scintillators in
the testing rig in the x-ray lab.

// Scintillator backplate

// Basic length variables
semitransparent = 0.618;
nearlytransparent = 0.309;

CenterSzintillator = [459/2, 380 - 80 - 172/2, 0];

// Toshiba Szintillator
SizeToshiba = [236, 172, 100];
difference(){
	cube([459, 380, 6]);
	translate(CenterSzintillator-SizeToshiba/2){
		cube(SizeToshiba);
	}
}

// Pingseng Szintillator
SizePinseng = [200, 200, 100];
translate([500,0,0]){
	difference(){
		cube([459, 380, 6]);
		translate(CenterSzintillator-SizePinseng/2){
			cube(SizePinseng);
		}
	}
}

// Applied Scintillation Technologies Szintillator
SizeAppScinTech = [106, 106, 100];
translate([1000,0,0]){
	difference(){
		cube([459, 380, 6]);
		translate(CenterSzintillator-SizeAppScinTech/2){
			cube(SizeAppScinTech);
		}
	}
}

error: pathspec 'DetectorMockup/ScintillatorBackplates.scad' did not match any file(s) known to git


added temp for tests

added temp for tests

include <resin/printer.scad>
$fn = 48;
$detailed = true;
rotate([90,0,0]) {
  printer();
}

error: pathspec 'temp.scad' did not match any file(s) known to git


'fleshing out' arm

'fleshing out' arm

use <StepMotor_28BYJ-48.scad>;
use <Hub_28BYJ-48.scad>;
include <Bearing_6807-2RS.scad>;

// global rendering parameters
$fn = 24;

// library examples
// translate([100, 100, 10]) { StepMotor28BYJ(); }
// stepperHub(10, 7, 6, 3.1, 1.5, 2.75);
//translate([0, 0, 8]) bearing6807_2RS();
// bearingInnerStep(bearing6807_2RS_d - iFitAdjust, 2, 2);
//shoulderBase(2, 55, 9.1, 3.1);

// interference fit adjustment for 3D printer
iFitAdjust = .4;

// shoulder base parameters
shoulderBaseHeight = 3;
shoulderBaseDiameter = 55;
shaftBossDiameter = 10;
mountScrewDiameter = 3.1;
bearingStep = 2; // size in mm of bearing interface step
// joint parameters
hubHeight = 10;
hubRadius = 7;
shaftHeight = 6;
shaftRadius = 3.1;
setScrewRadius = 1.5;
setScrewHeight = 2.75;
spokeWidth = 3;
spokes = 6;
screwTabs = 4;
screwTabHeight = 4;
armLength = 100;
// misc
baseDeckExtension = 50;
boundingBox = 8;
boundingBoxHalf = boundingBox / 2;
// 8 is distance from shaft center to screw center on x axis
// 35 is screw center to screw center on y axis
shaftCenterToMountHoldCenterXAxis = 8;
mountHoleCenterToMountHoleCenter = 35;
leadScrewDiameter = 8;
// forearm
forearmLength = 75;

/* Pieces in this model
** Shoulder:
*** Base plate
*** Top plate
*** Lower arm
*** Upper arm
** Forearm:
*** ?
** Hand:
*** ?
*/

// shoulder base
color([.7, .7, 1])
    shoulderBase(shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// shoulder stepper
rotate([0, 180, 0])
    translate([-8, 0, 10])
        StepMotor28BYJ();
// lower shoulder bearing
translate([0, 0, shoulderBaseHeight + bearingStep])
    %bearing6807_2RS();
// lower arm including the shoulder - arm joint
render()
color([1, .7, .7])
    translate([0, 0, shoulderBaseHeight + bearing6807_2RS_B])
        armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
// upper arm
//render()
color([.9, .7, .7])
    translate([0, 0, shoulderBaseHeight + ( 2*bearing6807_2RS_B) + (12 * bearingStep) - (.5 * bearingStep)])
        rotate([180, 0, 0])
            armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
// elbow joint pieces
// lower bearing
translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + bearingStep])
    %bearing6807_2RS();
// arm stepper
rotate([0, 180, 0])
    translate([armLength - 8, 0, bearingStep * 2])
        StepMotor28BYJ();
// forearm pieces
// lower
color([.1, .7, .1])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
//translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (14 *bearingStep)])
    forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
// upper
color([.2, .8, .2])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
//translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (14 *bearingStep)])
    rotate([180, 0, 0])
    forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
// forearm upper bearing
translate([-armLength, 0, shoulderBaseHeight + (2 * bearing6807_2RS_B) + (7 * bearingStep)])
    %bearing6807_2RS();
/*
deprecated
render()
    translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + (2* bearingStep)])
        armJointSpacer(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
*/

//bearingInnerStep(bearing6807_2RS_d - iFitAdjust, 2, 2);
module bearingInnerStep(bearingID, stepHeight, stepWidth) {
    difference() {
        union() {
            // this fits inside of the bearing
            cylinder(h = stepHeight * 2, d = bearingID);
            // this rests on the bearing inner lip
            cylinder(h = stepHeight, d = bearingID + stepWidth);
        }
        // remove center
        cylinder(h = stepHeight * 2, d = bearingID - (stepWidth * 2));
    }
}

//translate([0, 0, 12]) bearingOuterStep(bearing6807_2RS_D + iFitAdjust, 2, 2);
module bearingOuterStep(bearingOD, stepHeight, stepWidth) {
    //render(convexivity = 3)
    difference() {
        cylinder(h = stepHeight * 2, d = bearingOD + stepWidth);
        cylinder(h = stepHeight * 2, d = bearingOD - stepWidth);
        cylinder(h = stepHeight, d = bearingOD);
    }
}

// armJointSpacer(bearing6807_2RS_D - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
module armJointSpacer(bearingID, bearingOD, bearingStep, shaftBossDiameter, mountScrewDiameter) {
    union() {
        difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
            cylinder(h = bearingStep * 2, d = bearingID);
        }
        translate([0, 0, bearingStep * 2])
                bearingInnerStep(bearingID, bearingStep, bearingStep);
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * bearingStep) - screwTabHeight])
                    difference() {
                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }
                        cylinder(h = screwTabHeight, r = setScrewRadius);
                    }
    }
}

//shoulderBase(2, 55, 9.1, 3.1);
// WARNING: has some hard-coded non-parametric values in here!
module shoulderBase(shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter) {
    mountHoleDepth = shoulderBaseHeight;

    //render(convexivity = 3)
    difference() {
        union () {
            cylinder(h = shoulderBaseHeight, d = shoulderBaseDiameter);
            translate([0, 0, shoulderBaseHeight])
                bearingInnerStep(bearing6807_2RS_d - iFitAdjust, bearingStep, bearingStep);
            // 40 is the length of deck extension from the baseplate in x
            translate([0, -shoulderBaseDiameter / 2, 0])
                cube([baseDeckExtension, shoulderBaseDiameter, shoulderBaseHeight], center = false);
        }
        // motor shaft hole
        cylinder(h = shoulderBaseHeight + (bearingStep * 2), d = shaftBossDiameter);
        // mounting holes

        translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        // lead screw hole
        translate([baseDeckExtension - (leadScrewDiameter * 1.5), 0, 0])
            cylinder(h = shoulderBaseHeight, d = leadScrewDiameter + (leadScrewDiameter / 2));
    }
    // NOTE: need to add LM8UU mounts
}

module armLower(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength) {
    armWidth = bearingOD / 2;
    //render(convexivity = 3)
    difference() {
    union() {
        armInnerJoint(bearingOD, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight);
        translate([-armLength, 0, 0])
            armOuterJointBase(bearingOD, bearingStep, setScrewRadius, screwTabs, screwTabHeight);
        difference() {
            translate([-armLength, -armWidth / 2, 0])
                cube([armLength, armWidth, bearingStep * 2], center=false);
            cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-armLength, 0, 0])
                cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                cube([armLength - bearingOD - (boundingBox + boundingBoxHalf), armWidth - boundingBox, bearingStep * 2], center = false);
        }
        difference() {
            intersection() {

                translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([armLength - bearingOD - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
                for (i = [ bearingOD / 2 - boundingBoxHalf: armWidth : armLength]) {
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, 45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, -45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                }
            }

        }
   }
           // screw holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])
                       cylinder(h = screwTabHeight, r = setScrewRadius);
   }
}

module armOuterJointBase(bearingOD, bearingStep, setScrewRadius, screwTabs, screwTabHeight) {
    mountHoleDepth = bearingStep * 2;

    union() {
        difference() {
            union() {
                translate([0, 0, -(bearingStep * 2)])
                    cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
                translate([0, 0, bearingStep * 2])
                    rotate([0, 180, 0])
                        bearingOuterStep(bearingOD, bearingStep, bearingStep);
            }
            // motor shaft hole
            translate([0, 0, -(bearingStep * 2)])
                cylinder(h = shoulderBaseHeight + (bearingStep * 2), d = shaftBossDiameter);
            // mounting holes
            translate([0, 0, -(bearingStep * 2)]) {
                translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
                cylinder(h = mountHoleDepth, d = mountScrewDiameter);
                translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
                cylinder(h = mountHoleDepth, d = mountScrewDiameter);
            }
        }

    }
}

//armInnerJoint(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight);
module armInnerJoint(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight) {
    //translate([0, 0, hubHeight - (2 * stepHeight)])
    difference() {
        union() {
         difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + (setScrewRadius * 6));
            cylinder(h = bearingStep * 2, d = bearingOD);
//            translate([0, -bearingOD, 0])
//                cube([bearingOD, bearingOD * 2, bearingStep * 2]);
        }
        bearingOuterStep(bearingOD, stepHeight, stepWidth);
        // hub
        translate([0, 0, -(hubHeight - (2 * stepHeight))])
            stepperHub(hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight);
        // spokes
        radial_array(vec=[0, 0, 1], n = spokes)
                translate([hubRadius - (stepWidth / 2), -(spokeWidth / 2), stepHeight])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, stepHeight], center = false);
        // screw tabs for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])

                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }

                    }
        // screw holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])
                       cylinder(h = screwTabHeight, r = setScrewRadius);
    }
}

module forearmLower(bearingID, bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox) {
    armWidth = bearingOD / 2;

    rotate([180, 0, 0]) union() {
        boundingBoxHalf = boundingBox / 2;
        difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
            cylinder(h = bearingStep * 2, d = bearingID - (2 * bearingStep));
        }
        translate([0, 0, bearingStep * 2])
            bearingInnerStep(bearingID, bearingStep, bearingStep);
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * bearingStep) - screwTabHeight])
                    difference() {
                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }
                        cylinder(h = screwTabHeight, r = setScrewRadius);
                    }
        // hub
        translate([0, 0, hubHeight]) rotate([180, 0, 0])
            stepperHub(hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight);
        // spokes
        radial_array(vec=[0, 0, 1], n = spokes)
                translate([hubRadius - (stepWidth / 2), -(spokeWidth / 2), 0])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, 2 *stepHeight], center = false);
        // forearm extension
             difference() {
            translate([-forearmLength, -armWidth / 2, 0])
                cube([forearmLength, armWidth, bearingStep * 2], center=false);
            cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-forearmLength, 0, 0])
                cylinder(h = bearingStep * 2, d = bearingOD / 2);
                 // 4 on next line comes from dividing the bearingOD on the above line
            translate([-forearmLength + (bearingOD / 4) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                cube([forearmLength - (bearingOD/2) - (boundingBox + boundingBoxHalf), armWidth - boundingBox, bearingStep * 2], center = false);
        }

            intersection() {

                translate([-forearmLength + boundingBox * 2, -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([forearmLength - (bearingOD / 2) - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
                for (i = [ bearingOD / 2 - boundingBoxHalf: armWidth : forearmLength]) {
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, 45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, -45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                }
            }

    }
}

module copy_mirror(vec=[0,1,0]) {
    children();
    mirror(vec)
        children();
}

module radial_array(vec = [0,0,1], n = 4) {
    for ( i = [0 : n - 1] )
    {
        rotate( i * 360 / n, vec)
            children();
    }
}

use <StepMotor_28BYJ-48.scad>;
use <Hub_28BYJ-48.scad>;
include <Bearing_6807-2RS.scad>;

// global rendering parameters
$fn = 24;

// library examples
// translate([100, 100, 10]) { StepMotor28BYJ(); }
// stepperHub(10, 7, 6, 3.1, 1.5, 2.75);
//translate([0, 0, 8]) bearing6807_2RS();
// bearingInnerStep(bearing6807_2RS_d - iFitAdjust, 2, 2);
//shoulderBase(2, 55, 9.1, 3.1);

// interference fit adjustment for 3D printer
iFitAdjust = .6;

// shoulder base parameters
shoulderBaseHeight = 3;
shoulderBaseDiameter = 55;
shaftBossDiameter = 10;
mountScrewDiameter = 3.1;
bearingStep = 2; // size in mm of bearing interface step
// joint parameters
hubHeight = 10;
hubRadius = 7;
shaftHeight = 6;
shaftRadius = 3.1;
setScrewRadius = 1.5;
setScrewHeight = 2.75;
spokeWidth = 3;
spokes = 6;
screwTabs = 4;
screwTabHeight = 4;
armLength = 200;
// misc
baseDeckExtension = 50;
boundingBox = 8;
boundingBoxHalf = boundingBox / 2;
// 8 is distance from shaft center to screw center on x axis
// 35 is screw center to screw center on y axis
shaftCenterToMountHoldCenterXAxis = 8;
mountHoleCenterToMountHoleCenter = 35;
leadScrewDiameter = 8;
// forearm
forearmLength = 160;

/* Pieces in this model
** Shoulder:
*** Base plate
*** Top plate
*** Lower arm
*** Upper arm
** Forearm:
*** ?
** Hand:
*** ?
*/

// shoulder base
color([.7, .7, 1])
    shoulderBase(shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// shoulder stepper
rotate([0, 180, 0])
    translate([-8, 0, 10])
        StepMotor28BYJ();
// lower shoulder bearing
translate([0, 0, shoulderBaseHeight + bearingStep])
    %bearing6807_2RS();
// lower arm including the shoulder - arm joint
//render()
color([1, .7, .7])
    translate([0, 0, shoulderBaseHeight + bearing6807_2RS_B])
        armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
// arm joint pieces
translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + bearingStep])
    %bearing6807_2RS();
// arm stepper
rotate([0, 180, 0])
    translate([armLength - 8, 0, bearingStep * 2])
        StepMotor28BYJ();
// forearm pieces
color([.1, .7, .1])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
//translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (14 *bearingStep)])
render()
    forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
/*
render()
    translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + (2* bearingStep)])
        armJointSpacer(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
*/

//bearingInnerStep(bearing6807_2RS_d - iFitAdjust, 2, 2);
module bearingInnerStep(bearingID, stepHeight, stepWidth) {
    difference() {
        union() {
            // this fits inside of the bearing
            cylinder(h = stepHeight * 2, d = bearingID);
            // this rests on the bearing inner lip
            cylinder(h = stepHeight, d = bearingID + stepWidth);
        }
        // remove center
        cylinder(h = stepHeight * 2, d = bearingID - (stepWidth * 2));
    }
}

//translate([0, 0, 12]) bearingOuterStep(bearing6807_2RS_D + iFitAdjust, 2, 2);
module bearingOuterStep(bearingOD, stepHeight, stepWidth) {
    //render(convexivity = 3)
    difference() {
        cylinder(h = stepHeight * 2, d = bearingOD + stepWidth);
        cylinder(h = stepHeight * 2, d = bearingOD - stepWidth);
        cylinder(h = stepHeight, d = bearingOD);
    }
}

// armJointSpacer(bearing6807_2RS_D - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
module armJointSpacer(bearingID, bearingOD, bearingStep, shaftBossDiameter, mountScrewDiameter) {
    union() {
        difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
            cylinder(h = bearingStep * 2, d = bearingID);
        }
        translate([0, 0, bearingStep * 2])
                bearingInnerStep(bearingID, bearingStep, bearingStep);
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * bearingStep) - screwTabHeight])
                    difference() {
                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }
                        cylinder(h = screwTabHeight, r = setScrewRadius);
                    }
    }
}

//shoulderBase(2, 55, 9.1, 3.1);
// WARNING: has some hard-coded non-parametric values in here!
module shoulderBase(shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter) {
    mountHoleDepth = shoulderBaseHeight;

    //render(convexivity = 3)
    difference() {
        union () {
            cylinder(h = shoulderBaseHeight, d = shoulderBaseDiameter);
            translate([0, 0, shoulderBaseHeight])
                bearingInnerStep(bearing6807_2RS_d - iFitAdjust, bearingStep, bearingStep);
            // 40 is the length of deck extension from the baseplate in x
            translate([0, -shoulderBaseDiameter / 2, 0])
                cube([baseDeckExtension, shoulderBaseDiameter, shoulderBaseHeight], center = false);
        }
        // motor shaft hole
        cylinder(h = shoulderBaseHeight + (bearingStep * 2), d = shaftBossDiameter);
        // mounting holes

        translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        // lead screw hole
        translate([baseDeckExtension - (leadScrewDiameter * 1.5), 0, 0])
            cylinder(h = shoulderBaseHeight, d = leadScrewDiameter + (leadScrewDiameter / 2));
    }
    // NOTE: need to add LM8UU mounts
}

module armLower(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength) {
    armWidth = bearingOD / 2;
    //render(convexivity = 3)
    difference() {
    union() {
        armInnerJoint(bearingOD, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight);
        translate([-armLength, 0, 0])
            armOuterJointBase(bearingOD, bearingStep, setScrewRadius, screwTabs, screwTabHeight);
        difference() {
            translate([-armLength, -armWidth / 2, 0])
                cube([armLength, armWidth, bearingStep * 2], center=false);
            cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-armLength, 0, 0])
                cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                cube([armLength - bearingOD - (boundingBox + boundingBoxHalf), armWidth - boundingBox, bearingStep * 2], center = false);
        }
        difference() {
            intersection() {

                translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([armLength - bearingOD - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
                for (i = [ bearingOD / 2 - boundingBoxHalf: armWidth : armLength]) {
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, 45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, -45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                }
            }

        }
   }
           // screw holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])
                       cylinder(h = screwTabHeight, r = setScrewRadius);
   }
}

module armOuterJointBase(bearingOD, bearingStep, setScrewRadius, screwTabs, screwTabHeight) {
    mountHoleDepth = bearingStep * 2;

    union() {
        difference() {
            union() {
                translate([0, 0, -(bearingStep * 2)])
                    cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
                translate([0, 0, bearingStep * 2])
                    rotate([0, 180, 0])
                        bearingOuterStep(bearingOD, bearingStep, bearingStep);
            }
            // motor shaft hole
            translate([0, 0, -(bearingStep * 2)])
                cylinder(h = shoulderBaseHeight + (bearingStep * 2), d = shaftBossDiameter);
            // mounting holes
            translate([0, 0, -(bearingStep * 2)]) {
                translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
                cylinder(h = mountHoleDepth, d = mountScrewDiameter);
                translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
                cylinder(h = mountHoleDepth, d = mountScrewDiameter);
            }
        }

    }
}

//armInnerJoint(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight);
module armInnerJoint(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight) {
    //translate([0, 0, hubHeight - (2 * stepHeight)])
    difference() {
        union() {
         difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + (setScrewRadius * 6));
            cylinder(h = bearingStep * 2, d = bearingOD);
//            translate([0, -bearingOD, 0])
//                cube([bearingOD, bearingOD * 2, bearingStep * 2]);
        }
        bearingOuterStep(bearingOD, stepHeight, stepWidth);
        // hub
        translate([0, 0, -(hubHeight - (2 * stepHeight))])
            stepperHub(hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight);
        // spokes
        radial_array(vec=[0, 0, 1], n = spokes)
                translate([hubRadius - (stepWidth / 2), -(spokeWidth / 2), stepHeight])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, stepHeight], center = false);
        // screw tabs for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])

                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }

                    }
        // screw holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])
                       cylinder(h = screwTabHeight, r = setScrewRadius);
    }
}

module forearmLower(bearingID, bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox) {
    armWidth = bearingOD / 2;

    rotate([180, 0, 0]) union() {
        boundingBoxHalf = boundingBox / 2;
        difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
            cylinder(h = bearingStep * 2, d = bearingID - (2 * bearingStep));
        }
        translate([0, 0, bearingStep * 2])
            bearingInnerStep(bearingID, bearingStep, bearingStep);
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * bearingStep) - screwTabHeight])
                    difference() {
                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }
                        cylinder(h = screwTabHeight, r = setScrewRadius);
                    }
        // hub
        translate([0, 0, hubHeight]) rotate([180, 0, 0])
            stepperHub(hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight);
        // spokes
        radial_array(vec=[0, 0, 1], n = spokes)
                translate([hubRadius - (stepWidth / 2), -(spokeWidth / 2), 0])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, 2 *stepHeight], center = false);
        // forearm extension
             difference() {
            translate([-forearmLength, -armWidth / 2, 0])
                cube([forearmLength, armWidth, bearingStep * 2], center=false);
            cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-forearmLength, 0, 0])
                cylinder(h = bearingStep * 2, d = bearingOD / 2);
                 // 4 on next line comes from dividing the bearingOD on the above line
            translate([-forearmLength + (bearingOD / 4) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                #cube([forearmLength - (bearingOD/2) - (boundingBox + boundingBoxHalf), armWidth - boundingBox, bearingStep * 2], center = false);
        }

            intersection() {

                translate([-forearmLength + boundingBox * 2, -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([forearmLength - (bearingOD / 2) - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
                for (i = [ bearingOD / 2 - boundingBoxHalf: armWidth : forearmLength]) {
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, 45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, -45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                }
            }

    }
}

module copy_mirror(vec=[0,1,0]) {
    children();
    mirror(vec)
        children();
}

module radial_array(vec = [0,0,1], n = 4) {
    for ( i = [0 : n - 1] )
    {
        rotate( i * 360 / n, vec)
            children();
    }
}


Not sure if the last commit was fully up to date...

slop = .2;

//sized for m5 and 605
bearing_w = 5+slop;
bearing_d = 16;
bearing_r = bearing_d/2+slop;
bearing_inner_d = 8.5;
bearing_inner_r = bearing_inner_d/2;

bolt_d = 5;
bolt_r = bolt_d/2+slop;
bolt_head_r = 10/2+slop;
nut_r = 9/2+slop;

//these are for top-mounting the holder above your printer.
//Requires printing with support material!
top_length = 34;
top_thick = 6.5;

//sized for m8 and 608
//bearing_w = 7+slop;
//bearing_d = 22;
//bearing_r = bearing_d/2+slop;
//bearing_inner_d = 12;
//bearing_inner_r = bearing_inner_d/2;

//bolt_d = 8;
//bolt_r = bolt_d/2+slop;

separation = 100;
wall = 4;

!spool_roller();
top_spool_roller();

$fn=32;
module spool_roller(){
	difference(){
		union(){
			translate([0,0,wall+slop/2]) cube([separation+wall*2,wall*3+bearing_w,wall+wall+slop], center=true);
			for(i=[-separation/2, separation/2]) translate([i,0,0]) {
				translate([0,0,wall]) bearing_mount();

				cylinder(r1=bearing_r+wall*1.5, r2=bearing_r+wall+wall, h=2);

				translate([0,0,1.95]) cylinder(r1=bearing_r+wall+wall, r2=(bearing_w+wall+wall+wall)/2, h=wall+wall+slop-1.95);
			}
		}

		//center channel
		translate([0,0,wall+wall+slop]) scale([1,(bearing_w+wall)/(wall*2),1]) rotate([0,90,0]) cylinder(r=wall, h=separation*2, center=true, $fn=32);
	}
}

module top_spool_roller(){
    base = 5;
    lift = top_thick+base;

    mount_offset = 10;

	difference(){
		union(){
			translate([0,0,lift/2+wall/2+slop/2]) cube([separation+wall*2,wall*3+bearing_w,lift+wall+slop], center=true);

			for(i=[-separation/2, separation/2]) translate([i,0,0]) {
				translate([0,0,lift+wall/2]) bearing_mount();

                //chamfered base
				cylinder(r1=bearing_r+wall*1.5, r2=bearing_r+wall*2.5, h=3);
				translate([0,0,2.95]) cylinder(r1=bearing_r+wall*2.5, r2=(wall*3+bearing_w)/2, h=lift+wall*1.5);
			}
		}

		//center channel
		translate([0,0,lift+wall+slop]) hull(){
            //scale([1,(bearing_w+wall)/(wall*2),1]) rotate([0,90,0]) cylinder(r=wall, h=separation*2, center=true, $fn=32);
            translate([0,0,2]) scale([1,(bearing_w+wall)/(wall*2),1]) rotate([0,90,0]) cylinder(r=wall, h=separation*2, center=true, $fn=32);
        }

        //cutout for mounting atop the printer
        translate([mount_offset,0,0])
        difference(){
            union(){
                cube([top_length,30,lift*2], center=true);
                hull(){
                    cube([top_length,30,base*2], center=true);
                    translate([-wall/2,0,-lift]) cube([top_length,30,lift*2], center=true);
                }
            }

            translate([top_length/2,0,0]) rotate([0,-10,0]) cube([top_thick*2,40,base*2], center=true);
        }
	}
}

module bearing_mount(){
	translate([0,0,bearing_r+wall])
	rotate([-90,0,0])
	difference(){
		union(){
			for(i=[0,1]) mirror([0,0,i]) translate([0,0,-wall*1.5-bearing_w/2]) {
				translate([-(bearing_r+wall),0,0]) cube([(bearing_r+wall)*2, bearing_r+wall+wall, wall]);
				cylinder(r=(bearing_r+wall/2)/cos(30), h=wall, $fn=6);
				translate([0,0,wall]) cylinder(r=bearing_r, r2=bearing_inner_r, h=wall/2);
			}
		}

		cap_cylinder(r=bolt_r, h=14, center=true);

		translate([0,0,-wall*1.5-bearing_w/2-wall/2]) cap_cylinder(r=bolt_head_r, h=wall*1.4);
		translate([0,0,wall*1.4+bearing_w/2-wall/2]) cylinder(r1=nut_r, r2=nut_r+slop, h=wall*2, $fn=6);

	}
}

module cap_cylinder(r=1, h=1, center=false){
	render() union(){
		cylinder(r=r, h=h, center=center);
		intersection(){
			rotate([0,0,22.5]) cylinder(r=r/cos(180/8), h=h, $fn=8, center=center);
			translate([0,-r/cos(180/4),0]) rotate([0,0,0]) cylinder(r=r/cos(180/4), h=h, $fn=4, center=center);
		}
	}
}

slop = .2;

//sized for m5 and 605
bearing_w = 5+slop;
bearing_d = 16;
bearing_r = bearing_d/2+slop;
bearing_inner_d = 8.5;
bearing_inner_r = bearing_inner_d/2;

bolt_d = 5;
bolt_r = bolt_d/2+slop;
bolt_head_r = 10/2+slop;
nut_r = 9/2+slop;

//these are for top-mounting the holder above your printer.
//Requires printing with support material!
top_length = 34;
top_thick = 6.5;

//sized for m8 and 608
//bearing_w = 7+slop;
//bearing_d = 22;
//bearing_r = bearing_d/2+slop;
//bearing_inner_d = 12;
//bearing_inner_r = bearing_inner_d/2;

//bolt_d = 8;
//bolt_r = bolt_d/2+slop;

separation = 100;
wall = 4;

spool_roller();
!top_spool_roller();

$fn=32;
module spool_roller(){
	difference(){
		union(){
			translate([0,0,wall+slop/2]) cube([separation+wall*2,wall*3+bearing_w,wall+wall+slop], center=true);
			for(i=[-separation/2, separation/2]) translate([i,0,0]) {
				translate([0,0,wall]) bearing_mount();

				cylinder(r1=bearing_r+wall*1.5, r2=bearing_r+wall+wall, h=2);

				translate([0,0,1.95]) cylinder(r1=bearing_r+wall+wall, r2=(bearing_w+wall+wall+wall)/2, h=wall+wall+slop-1.95);
			}
		}

		//center channel
		translate([0,0,wall+wall+slop]) scale([1,(bearing_w+wall)/(wall*2),1]) rotate([0,90,0]) cylinder(r=wall, h=separation*2, center=true, $fn=32);
	}
}

module top_spool_roller(){
    base = 5;
    lift = top_thick+base;

    mount_offset = 10;

	difference(){
		union(){
			translate([0,0,lift/2+wall/2+slop/2]) cube([separation+wall*2,wall*3+bearing_w,lift+wall+slop], center=true);

			for(i=[-separation/2, separation/2]) translate([i,0,0]) {
				translate([0,0,lift+wall/2]) bearing_mount();

                //chamfered base
				cylinder(r1=bearing_r+wall*1.5, r2=bearing_r+wall*2.5, h=3);
				translate([0,0,2.95]) cylinder(r1=bearing_r+wall*2.5, r2=(wall*3+bearing_w)/2, h=lift+wall*1.5);
			}
		}

		//center channel
		translate([0,0,lift+wall+slop]) hull(){
            //scale([1,(bearing_w+wall)/(wall*2),1]) rotate([0,90,0]) cylinder(r=wall, h=separation*2, center=true, $fn=32);
            translate([0,0,2]) scale([1,(bearing_w+wall)/(wall*2),1]) rotate([0,90,0]) cylinder(r=wall, h=separation*2, center=true, $fn=32);
        }

        //cutout for mounting atop the printer
        translate([mount_offset,0,0])
        difference(){
            union(){
                cube([top_length,30,lift*2], center=true);
                hull(){
                    cube([top_length,30,base*2], center=true);
                    translate([-wall/2,0,-lift]) cube([top_length,30,lift*2], center=true);
                }
            }

            translate([top_length/2,0,0]) rotate([0,-10,0]) cube([top_thick*2,40,base*2], center=true);
        }
	}
}

module bearing_mount(){
	translate([0,0,bearing_r+wall])
	rotate([-90,0,0])
	difference(){
		union(){
			for(i=[0,1]) mirror([0,0,i]) translate([0,0,-wall*1.5-bearing_w/2]) {
				translate([-(bearing_r+wall),0,0]) cube([(bearing_r+wall)*2, bearing_r+wall+wall, wall]);
				cylinder(r=(bearing_r+wall/2)/cos(30), h=wall, $fn=6);
				translate([0,0,wall]) cylinder(r=bearing_r, r2=bearing_inner_r, h=wall/2);
			}
		}

		cap_cylinder(r=bolt_r, h=14, center=true);

		translate([0,0,-wall*1.5-bearing_w/2-wall/2]) cap_cylinder(r=bolt_head_r, h=wall*1.4);
		translate([0,0,wall*1.4+bearing_w/2-wall/2]) cylinder(r1=nut_r, r2=nut_r+slop, h=wall*2, $fn=6);

	}
}

module cap_cylinder(r=1, h=1, center=false){
	render() union(){
		cylinder(r=r, h=h, center=center);
		intersection(){
			rotate([0,0,22.5]) cylinder(r=r/cos(180/8), h=h, $fn=8, center=center);
			translate([0,-r/cos(180/4),0]) rotate([0,0,0]) cylinder(r=r/cos(180/4), h=h, $fn=4, center=center);
		}
	}
}


Add a bar mount support

Add a bar mount support

tube_diameter = 28;
space_margin = 1;
thickness = 5;
screw_diameter = 5;
screw_head_thickness = 5;

a = tube_diameter + 2* space_margin +2*thickness;
difference(){
	union(){
		//Main part
		cube(size=[a,a,a], center = true);

		//Screw tube
		translate([0, a/2+screw_diameter/2,0]) difference(){
			cylinder(r = screw_diameter/2+thickness, h = a, center=				true);
			cylinder(r = screw_diameter/2, h = a, center=true);
		}
		//Second screw tube
		translate([0, -a/2-screw_diameter/2,0]) difference(){
			cylinder(r = screw_diameter/2+thickness, h = a, center=				true);
			cylinder(r = screw_diameter/2, h = a, center=true);

		}
	}
	rotate([0,90,0])  cylinder(r=tube_diameter/2. + space_margin, h= 2*a, center = true);
   cube(size =[2*a, 2*a,tube_diameter/5.], center = true);
	translate([0,-a/2-screw_diameter/2,a/2]) cylinder(r = screw_diameter/2+thickness+0.1, h = 2*screw_head_thickness, center=				true);
	translate([0,-a/2-screw_diameter/2,-a/2]) cylinder(r = screw_diameter/2+thickness+0.1, h = 2*screw_head_thickness, center=				true);
	translate([0,+a/2+screw_diameter/2,a/2]) cylinder(r = screw_diameter/2+thickness+0.1, h = 2*screw_head_thickness, center=				true);
	translate([0,+a/2+screw_diameter/2,-a/2]) cylinder(r = screw_diameter/2+thickness+0.1, h = 2*screw_head_thickness, center=				true);
}

error: pathspec 'Hardware/bar_mount.scad' did not match any file(s) known to git


Fixed typo in PinsDev.scad in Sandbox.

Fixed typo in PinsDev.scad in Sandbox.

include <../config/config.scad>

// playground for pins libary
// Modules to call = pin(), pinpeg(), pintack(), pinhole()
//
// Parameters :
//
// h = Length or height of pin/hole.
// r = radius of pin body (Default = PinDiameter/2).
// lh = Height of lip.
// lt = Thickness of lip (Also adjusts slot width to allow legs to close).
// t = Pin tolerance.
// bh = Base Height (pintack only).
// br = Base Radius (pintack only).
// tight = Hole friction, set to false if you want a joint that spins easily (pinhole only)
// fixed = Hole Twist, set to true so pins can't spin (pinhole only)
//	Side = Orientates pins on their side for printing : true/false (not pinhole).

translate([-25,0,0])
	pin();

translate([0,-20,0])
	pintack();

translate([25,0,0])
	pinpeg(h=20);

translate([-40,0,0])
	pin(side=true);

translate([0,-40,0])
	pintack(side=true);

translate([40,0,0])
	pinpeg(h=20, side=true);

translate([0,20,0])
	pinhole(fixed=true);

translate([10,0,0])difference(){
	cylinder(r=5.5,h=14);
	pinhole();
}

translate([-10,0,0])difference(){
	cylinder(r=5.5,h=14);
	pinhole(fixed=true);
}

include <../config/config.scad>

// playground for pins libary
// Modules to call = pin(), pinpeg(), pintack(), pinhole()
//
// Parameters :
//
// h = Length or height of pin/hole.
// r = radius of pin body (Default = PinDiameter/2).
// lh = Height of lip.
// lt = Thickness of lip (Also adjusts slot width to allow legs to close).
// t = Pin tolerance.
// bh = Base Height (pintack only).
// br = Base Radius (pintack only).
// tight = Hole friction, set to false if you want a joint that spins easily (pinhole only)
// fixed = Hole Twist, set to true so pins can't spin (pinhole only)
//	Side = Orientates pins on their side for printing : true/false (not pinhole).

translate([-25,0,0])
	pin();

translate([0,-20,0])
	pintack();

translate([25,0,0])
	pinpeg(l=10);

translate([-40,0,0])
	pin(side=true);

translate([0,-40,0])
	pintack(side=true);

translate([40,0,0])
	pinpeg(l=10, side=true);

translate([0,20,0])
	pinhole(fixed=true);

translate([10,0,0])difference(){
	cylinder(r=5.5,h=14);
	pinhole();
}

translate([-10,0,0])difference(){
	cylinder(r=5.5,h=14);
	pinhole(fixed=true);
}


cleanup

cleanup