pen holder part (shelf)

pen holder part (shelf)

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


inner and outer pipes separated - need to process the connectors still

eps = 0.01;
wall = 1.3;

launch_side = 22;
launch_h = 180;

conn_phi = 25;
conn_h = 20;

module screw_mount()
{
  s = 10;
  h = 5;
  difference()
  {
    translate([-s/2, -s/2, 0])
      cube([s, s, h]);
    translate([0, 0, -eps])
      #cylinder(d=4, h=h+2*eps, $fn=50);
  }
}

module triangle_2d(side)
{
  dx = -side/2;
  dy = 0;
  translate([dx, 0, 0])
  polygon( points=[
    [0, 0],
    [side, 0],
    [cos(60)*side, sin(60)*side]
  ] );
}

module triangle_2d_int(side)
{
  offset(r=-wall)
    triangle_2d(side);
}

module pipe_connector(d, h, $fn=200)
{
  cylinder(d=d, h=h);
}

module outer_pipe()
{
  // rocket side
  translate([0, launch_h+eps, 0])
    rotate([90, 0, 0])
      linear_extrude(height=launch_h)
        triangle_2d(launch_side);
  // rubber pipe side
  dz = launch_side * sin(60);
  translate([0, -conn_phi/2, dz])
    pipe_connector(conn_phi, 20);
  // interconenction of both
  translate([-conn_phi/2, -conn_phi, 0])
    cube([conn_phi, conn_phi, dz]);
}

module inner_pipe()
{
  // rocket side
  translate([0, launch_h+eps, 0])
    rotate([90, 0, 0])
      linear_extrude(height=launch_h+2*eps)
        triangle_2d_int(launch_side);
  // rubber pipe side
  dz = launch_side * sin(60);
  translate([0, -conn_phi/2, dz])
    pipe_connector(conn_phi-2*wall, 20+eps);
  // interconenction of both
  /*
  hull()
  {
    rotate([90, 0, 0])
      triangular_prism(launch_side, 0.1);
    translate([0, 0, dz])
      for(r=[0:5:40])
        rotate([r, 0, 0])
          translate([0, -conn_phi/2, 0])
            pipe_connector(conn_phi-r/5, 0.1, $fn=50);
  }
  */
}

module launcher()
{
  difference()
  {
//    outer_pipe();
    inner_pipe();
  }
  // TODO screw holes :P
}

launcher();

eps = 0.01;
phi = 25;
wall = 1.3;
side = 22;

module screw_mount()
{
  s = 10;
  h = 5;
  difference()
  {
    translate([-s/2, -s/2, 0])
      cube([s, s, h]);
    translate([0, 0, -eps])
      #cylinder(d=4, h=h+2*eps, $fn=50);
  }
}

module triangle_2d(side)
{
  dx = -side/2;
  dy = 0;
  translate([dx, 0, 0])
  polygon( points=[
    [0, 0],
    [side, 0],
    [cos(60)*side, sin(60)*side]
  ] );
}

module triangular_prism(side, height)
{
  linear_extrude(height=height)
    triangle_2d(side);
}

module pipe_connector(d, h)
{
  cylinder(d=d, h=h, $fn=200);
}

module inner_pipe()
{
  // rocket side
  ph = 180;
  translate([0, ph, 0])
    rotate([90, 0, 0])
      triangular_prism(side, ph);
  // rubber pipe side
  dz = side * sin(60);
  translate([0, -phi/2, dz])
    pipe_connector(phi, 20);
  // interconenction of both
  hull()
  {
    rotate([90, 0, 0])
      triangular_prism(side, 0.1);
    translate([0, 0, dz])
      for(r=[0:5:40])
        rotate([r, 0, 0])
          translate([0, -phi/2, 0])
            pipe_connector(phi-r/5, 0.1, $fn=50);
  }
}

module launcher()
{
  inner_pipe();
}

launcher();


fanduct: fix compile warnings/errors

fanduct: fix compile warnings/errors

include <config.scad>
include <fanduct.h>

use <scad-utils/transformations.scad>
use <scad-utils/lists.scad>
use <scad-utils/shapes.scad>
use <list-comprehension-demos/sweep.scad>
use <scad-utils/shapes.scad>
use <list-comprehension-demos/skin.scad>
use <thing_libutils/misc.scad>
use <thing_libutils/splines.scad>
use <thing_libutils/sweep.scad>
use <thing_libutils/transforms.scad>
use <thing_libutils/shapes.scad>
use <thing_libutils/attach.scad>
use <thing_libutils/naca_sweep.scad>
use <thing_libutils/fan_5015S.scad>
include <thing_libutils/fan_5015S.h>

// helper functions to work on headered-arrays (where first entry is column headers)
function nSpline_header(S, N) =
assert(N > 1)
let(slice = v_slice(S,start=1))
concat(
    [S[0]],
    nSpline(slice, N)
    );

// data for duct geometry
// ss parameter is initial size of duct (e.g. for fan throat/output)
// returned data has a header row
// warning, don't set r to 0 or rendering breaks!
function gen_data(ss) = [
    [       "Tx","Ty","Tz",     "Sx",   "Sy", "Rx", "Ry",  "Rz", "r"],
    [     ss.x/4, -27,  25,   ss.x/2,   ss.y,   60,   00,  00, .01],
    [ 2.5+ss.x/4, -21,  21, 5+ss.x/2,   ss.y,   60,   00,  00, .1 ],
    /*[         15, -18,  30,       11,     20,   13,    0,  00, .4 ],*/
    /*[         17,  -8,  20,       11,     17,   11,  -10,  00, .5 ],*/
    [         16, -10,  15,       17,     20,   30,  -15,  00, .7 ],
    [         15,  -4,  10,       11,     19,   20,  -30,  00, .7 ],
    [         12,   0,   5,        6,     13,    0,  -45,  00, .8 ],
];

fanduct_data = gen_data(fanduct_throat_size_withwall);

module duct(A, fanduct_wallthick=2, N=100, d=2)
{
    // rounded bugs out when rendering if r value is 0 :/
    function shape_profile(size,r) = rounded_rectangle_profile(size=size,r=r);
    /*function shape_profile(size,r) = rectangle_profile(size);*/

    module showcontrols(V, N=100)
    {
        function gen_T(V) =
        [
           for (i=[0:len(V)-2])
           let(R = vec3(geth(V,["Rx","Ry"],i)))
           let(T = geth(V,["Tx","Ty","Tz"],i))
           translation(T)*rotation(v_mul(R,[1,-1,1]))
        ];

        T = gen_T(A);
        for (i=[0:len(T)-1])
        let(t=T[i])
        multmatrix(t)
        color("red")
        let(S = [geth(A,"Sx",i),geth(A,"Sy",i)])
        let(r = geth(A,"r",i))
        let(r_ = [.5*r*S.x, .5*r*S.y])
        let(h=.5)
        difference()
        {
            linear_extrude(height=h,center=true)
            polygon(shape_profile(size=S+[1,1], r=r_));

            linear_extrude(height=h+.1,center=true)
            polygon(shape_profile(size=S, r=r_));

            /*torus(r=a[3], radial_width=1.5);*/
        }

        function gen_dat(V) =
           [
           for (i=[0:len(V)-2])
               let(S = geth(V,["Sx","Sy"],i))
               let(R = vec3(geth(V,["Rx","Ry"],i)))
               let(T = geth(V,["Tx","Ty","Tz"],i))
               let(v=to_3d(circle_profile(r=.5)))
               let(dat = R_(R.x, R.y, R.z, v))
               T_(T.x,T.y,T.z, dat)
           ];
        outer = gen_dat(nSpline_header(A,N));    // outer skin
        skin(outer);
    }

    // generate transformed shapes
    function gen_dat(V) =
       [
       for (i=[0:len(V)-2])
           let(S = geth(V,["Sx","Sy"],i))
           let(r = [S.x*.5*geth(V,"r",i), S.y*.5*geth(V,"r",i)])
           let(v=to_3d(shape_profile(size=S,r=r)))
           let(R = vec3(geth(V,["Rx","Ry"],i)))
           let(T = geth(V,["Tx","Ty","Tz"],i))
           let(dat = R_(R.x, R.y, R.z, v=v))
           T_(T.x,T.y,T.z, dat)
       ];

    // inner skin data: modify tube diameter
    function modify_inner(S, subtract) = array_header_col_subtract(S, ["Sx", "Sy"], subtract);

    module sweepshape(V_outer,interp=true, N=100)
    {
        // inner skin is outer, but smaller size and reversed (so it will go back to start and join)
        V_inner = modify_inner(reverse_header(V_outer), fanduct_wallthick);
        if(interp)
        {
            outer = gen_dat(nSpline_header(V_outer,N));    // outer skin
            inner = gen_dat(nSpline_header(V_inner,N));    // inner skin
            sweep(concat(outer, inner), close = true, showslices = false);
            /*sweep(outer, close = true, showslices = false);*/
            /*skin(concat(outer, inner), loop=true);*/
        }
        else
        {
            outer = gen_dat(V_outer);    // outer skin
            inner = gen_dat(V_inner);    // inner skin
            sweep(concat(outer, inner), close = true, showslices = true);
        }
    }

    function mirrorshape(S, size) =
    let(cols = header_col_index(S,["Tx","Rx","Ry"]))
    concat([S[0]],
    [
        for(i=[1:len(S)-1])
        [
        for(j=[0:len(S[0])-1])
            v_contains(cols,j) ? -S[i][j] :
            S[i][j]
        ]
    ]);

    // debug experiment, mirror + join path for both duct arms
    /*A_ = mirrorshape(A);*/
    /*A__ = reverse_header(A_);*/
    /*A___ = concat_header(A__,A);*/
    /*sweepshape(A___,true);*/

    if($debug_mode)
    {
        /*tx(15)*/
        /*sweep(gen_dat(A), close = false, slices = true);*/

        /*tx(-15)*/
        showcontrols(A);
    }

    material(Mat_Plastic)
    sweepshape(A,true);
}

module mirrorcopy(axis)
{
    children();
    mirror(axis)
    children();
}

module fanduct_throat(throat_seal_h)
{
    difference()
    {
        union()
        {
            hull()
            {
                ty((fanduct_throat_size_withwall.y)/2)
                cubea([fanduct_throat_size.x,fanduct_throat_size.y,throat_seal_h]+XY*fanduct_wallthick,align=Z-Y);

                tz(seal_height)
                ty(fanduct_throat_size.y/2 - 47)
                tz(11.34/2)
                cylindera(h=fanduct_throat_size_withwall.x, d=7, orient=X);
            }

        }

        tz(-.1)
        cubea([fanduct_throat_size.x,fanduct_throat_size.y,1000],align=Z);

        seal_height = 4;
        tz(seal_height)
        {
            ty((fanduct_throat_size.y)/2)
            cubea([fanduct_throat_size.x,1000,1000],align=Z-Y, extra_size=.1*Y, extra_align=-Z);

            ty(-(fanduct_throat_size_withwall.y)/2)
            tz(-5)
            cubea([fanduct_throat_size.x,1000,1000],align=Z-Y, extra_size=.1*Y, extra_align=-Z);

            tz(-seal_height+2*mm)
            cubea([3.8,1000,1000],align=Z+Y);

            ty(fanduct_throat_size.y/2 - 47)
            tz(11.34/2)
            cylindera(h=1000, d=3.65, orient=X);
        }
    }

    ry(45)
    cubea([fanduct_wallthick/sqrt(2),fanduct_throat_size_withwall.y,fanduct_wallthick/sqrt(2)]);
}

module fanduct(part)
{
    /*$fn=is_build?$fn:48;*/

    A = fanduct_data;

    mirrorcopy(X)
    {
        duct(A=A, fanduct_wallthick=fanduct_wallthick, N=$fn, $debug_mode=true);
    }

    tx(-geth(A,"Tx",0))
    t(geth(A,["Tx","Ty","Tz"],0))
    r(geth(A,["Rx","Ry","Rz"],0))
    {
        throat_seal_h = 13*mm;

        material(Mat_Plastic)
        rz(180)
        fanduct_throat(throat_seal_h);

        fanduct_conn_fan = [N,-Z];
        rz(180)
        tz(2)
        attach(fanduct_conn_fan, fan_5015S_conn_flowoutput, 0)
        fan_5015S();
    }
}

module part_fanduct()
{
    ry(180)
    t(-geth(fanduct_data,["Tx","Ty","Tz"],0))
    r(-geth(fanduct_data,["Rx","Ry","Rz"],0))
    difference()
    fanduct();
}

if(false)
{
   $debug_mode=true;
   fanduct();
}

include <config.scad>
include <fanduct.h>

use <scad-utils/transformations.scad>
use <scad-utils/lists.scad>
use <scad-utils/shapes.scad>
use <list-comprehension-demos/sweep.scad>
use <scad-utils/shapes.scad>
use <list-comprehension-demos/skin.scad>
use <thing_libutils/misc.scad>
use <thing_libutils/splines.scad>
use <thing_libutils/sweep.scad>
use <thing_libutils/transforms.scad>
use <thing_libutils/shapes.scad>
use <thing_libutils/attach.scad>
use <thing_libutils/naca_sweep.scad>
use <thing_libutils/fan_5015S.scad>
include <thing_libutils/fan_5015S.h>

// helper functions to work on headered-arrays (where first entry is column headers)
function nSpline_header(S, N) =
let(slice = v_slice(S,start=1))
concat(
    [S[0]],
    nSpline(slice, N)
    );

// data for duct geometry
// ss parameter is initial size of duct (e.g. for fan throat/output)
// returned data has a header row
// warning, don't set r to 0 or rendering breaks!
function gen_data(ss) = [
    [       "Tx","Ty","Tz",     "Sx",   "Sy", "Rx", "Ry",  "Rz", "r"],
    [     ss.x/4, -27,  25,   ss.x/2,   ss.y,   60,   00,  00, .01],
    [ 2.5+ss.x/4, -21,  21, 5+ss.x/2,   ss.y,   60,   00,  00, .1 ],
    /*[         15, -18,  30,       11,     20,   13,    0,  00, .4 ],*/
    /*[         17,  -8,  20,       11,     17,   11,  -10,  00, .5 ],*/
    [         16, -10,  15,       17,     20,   30,  -15,  00, .7 ],
    [         15,  -4,  10,       11,     19,   20,  -30,  00, .7 ],
    [         12,   0,   5,        6,     13,    0,  -45,  00, .8 ],
];

fanduct_data = gen_data(fanduct_throat_size_withwall);

module duct(A, fanduct_wallthick=2, N=100, d=2)
{
    // rounded bugs out when rendering if r value is 0 :/
    function shape_profile(size,r) = rounded_rectangle_profile(size=size,r=r);
    /*function shape_profile(size,r) = rectangle_profile(size);*/

    module showcontrols(V)
    {
        function gen_T(V) =
        [
           for (i=[0:len(V)-2])
           let(R = vec3(geth(V,["Rx","Ry"],i)))
           let(T = geth(V,["Tx","Ty","Tz"],i))
           translation(T)*rotation(v_mul(R,[1,-1,1]))
        ];

        T = gen_T(A);
        for (i=[0:len(T)-1])
        let(t=T[i])
        multmatrix(t)
        color("red")
        let(S = [geth(A,"Sx",i),geth(A,"Sy",i)])
        let(r = geth(A,"r",i))
        let(r_ = [.5*r*S.x, .5*r*S.y])
        let(h=.5)
        difference()
        {
            linear_extrude(height=h,center=true)
            polygon(shape_profile(size=S+[1,1], r=r_));

            linear_extrude(height=h+.1,center=true)
            polygon(shape_profile(size=S, r=r_));

            /*torus(r=a[3], radial_width=1.5);*/
        }

        function gen_dat(V) =
           [
           for (i=[0:len(V)-2])
               let(S = geth(V,["Sx","Sy"],i))
               let(R = vec3(geth(V,["Rx","Ry"],i)))
               let(T = geth(V,["Tx","Ty","Tz"],i))
               let(v=to_3d(circle_profile(r=.5)))
               let(dat = R_(R.x, R.y, R.z, v))
               T_(T.x,T.y,T.z, dat)
           ];
        outer = gen_dat(nSpline_header(A,N));    // outer skin
        skin(outer);
    }

    // generate transformed shapes
    function gen_dat(V) =
       [
       for (i=[0:len(V)-2])
           let(S = geth(V,["Sx","Sy"],i))
           let(r = [S.x*.5*geth(V,"r",i), S.y*.5*geth(V,"r",i)])
           let(v=to_3d(shape_profile(size=S,r=r)))
           let(R = vec3(geth(V,["Rx","Ry"],i)))
           let(T = geth(V,["Tx","Ty","Tz"],i))
           let(dat = R_(R.x, R.y, R.z, v=v))
           T_(T.x,T.y,T.z, dat)
       ];

    // inner skin data: modify tube diameter
    function modify_inner(S, subtract) = array_header_col_subtract(S, ["Sx", "Sy"], subtract);

    module sweepshape(V_outer,interp=true)
    {
        // inner skin is outer, but smaller size and reversed (so it will go back to start and join)
        V_inner = modify_inner(reverse_header(V_outer), fanduct_wallthick);
        if(interp)
        {
            outer = gen_dat(nSpline_header(V_outer,N));    // outer skin
            inner = gen_dat(nSpline_header(V_inner,N));    // inner skin
            sweep(concat(outer, inner), close = true, showslices = false);
            /*sweep(outer, close = true, showslices = false);*/
            /*skin(concat(outer, inner), loop=true);*/
        }
        else
        {
            outer = gen_dat(V_outer);    // outer skin
            inner = gen_dat(V_inner);    // inner skin
            sweep(concat(outer, inner), close = true, showslices = true);
        }
    }

    function mirrorshape(S, size) =
    let(cols = header_col_index(S,["Tx","Rx","Ry"]))
    concat([S[0]],
    [
        for(i=[1:len(S)-1])
        [
        for(j=[0:len(S[0])-1])
            v_contains(cols,j) ? -S[i][j] :
            S[i][j]
        ]
    ]);

    // debug experiment, mirror + join path for both duct arms
    /*A_ = mirrorshape(A);*/
    /*A__ = reverse_header(A_);*/
    /*A___ = concat_header(A__,A);*/
    /*sweepshape(A___,true);*/

    if($debug_mode)
    {
        /*tx(15)*/
        /*sweep(gen_dat(A), close = false, slices = true);*/

        /*tx(-15)*/
        showcontrols(A);
    }

    material(Mat_Plastic)
    sweepshape(A,true);
}

module mirrorcopy(axis)
{
    children();
    mirror(axis)
    children();
}

module fanduct_throat(throat_seal_h)
{
    difference()
    {
        union()
        {
            hull()
            {
                ty((fanduct_throat_size_withwall.y)/2)
                cubea([fanduct_throat_size.x,fanduct_throat_size.y,throat_seal_h]+XY*fanduct_wallthick,align=Z-Y);

                tz(seal_height)
                ty(fanduct_throat_size.y/2 - 47)
                tz(11.34/2)
                cylindera(h=fanduct_throat_size_withwall.x, d=7, orient=X);
            }

        }

        tz(-.1)
        cubea([fanduct_throat_size.x,fanduct_throat_size.y,1000],align=Z);

        seal_height = 4;
        tz(seal_height)
        {
            ty((fanduct_throat_size.y)/2)
            cubea([fanduct_throat_size.x,1000,1000],align=Z-Y, extra_size=.1*Y, extra_align=-Z);

            ty(-(fanduct_throat_size_withwall.y)/2)
            tz(-5)
            cubea([fanduct_throat_size.x,1000,1000],align=Z-Y, extra_size=.1*Y, extra_align=-Z);

            tz(-seal_height+2*mm)
            cubea([3.8,1000,1000],align=Z+Y);

            ty(fanduct_throat_size.y/2 - 47)
            tz(11.34/2)
            cylindera(h=1000, d=3.65, orient=X);
        }
    }

    ry(45)
    cubea([fanduct_wallthick/sqrt(2),fanduct_throat_size_withwall.y,fanduct_wallthick/sqrt(2)]);
}

module fanduct(part)
{
    $fn=is_build?$fn:48;

    A = fanduct_data;

    mirrorcopy(X)
    {
        duct(A=A, fanduct_wallthick=fanduct_wallthick, N=$fn, $debug_mode=true);
    }

    tx(-geth(A,"Tx",0))
    t(geth(A,["Tx","Ty","Tz"],0))
    r(geth(A,["Rx","Ry","Rz"],0))
    {
        throat_seal_h = 13*mm;

        material(Mat_Plastic)
        rz(180)
        fanduct_throat(throat_seal_h);

        fanduct_conn_fan = [N,-Z];
        rz(180)
        tz(2)
        attach(fanduct_conn_fan, fan_5015S_conn_flowoutput, 0)
        fan_5015S();
    }
}

module part_fanduct()
{
    ry(180)
    t(-13)
    t(-geth(fanduct_data,["Tx","Ty","Tz"],0))
    r(-geth(fanduct_data,["Rx","Ry","Rz"],0))
    difference()
    fanduct();
}

if(false)
{
   $debug_mode=true;
   fanduct();
}


cylinder -> cone

cylinder -> cone

eps=0.01;

module bed_foot()
{
  h=60;
  d=52;
  difference()
  {
    cylinder(d1=d+10, d2=d, h=h, $fn=200);
    {
      $fn=50;
      // screw drill
      translate(-eps*[0,0,1])
        cylinder(d=4.5, h=h+2*eps);
      // screw guide
      translate(10*[0,0,1])
        cylinder(d1=10, d2=30, h=h);
    }
  }
}

bed_foot();

eps=0.01;

module bed_foot()
{
  h=60;
  d=52;
  difference()
  {
    cylinder(d=d, h=h, $fn=200);
    {
      $fn=50;
      // screw drill
      translate(-eps*[0,0,1])
        cylinder(d=4.5, h=h+2*eps);
      // screw guide
      translate(10*[0,0,1])
        cylinder(d1=10, d2=30, h=h);
    }
  }
}

bed_foot();


Added comment about laser cutting and kerf width.

//See:
// http://edutechwiki.unige.ch/en/OpenScad_beginners_tutorial
// https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/

// Global variables.
overcut = 0.1;  // Overcut for solid difference(), to assure complete holes.
overlap = 0.1;  // Intersection for solid union() to avoid the manifold problem.

include <misc_parts.scad>;
include <boards.scad>;
include <rounded_cube.scad>;

// Box internal size.
x_size  = 115.0;
y_size  = 144.0;
z_size  =  29.0;
thick   =   2.2;
chamfer =  13.0;

// Mounting screw holes.
screw_hole1_y = 24;
screw_hole2_y = y_size - 26;
screw_diam    = 3.6;

// Position and size of push button hole.
button_x = x_size;
button_y = 64;
button_z = 16.0;
button_d = 6.4;

// Position and size of power socket hole.
psocket_x = x_size / 2;
psocket_z = 7;
psocket_d = 8.2;

// Position and size for temperature sensor grommet.
tsensor_x  = -thick - 1;
tsensor_y  = 78;
tsensor_z  = 13;
tsensor_h  = thick + 9;
tsensor_d1 = 9.0;
tsensor_d2 = 5.5;

// Positon and size for boiler cable grommet (cable is 5.5 x 3.5 mm).
bcable_x  = 19;
bcable_y  = -thick - 1;
bcable_z  = 9.5;
bcable_h  = thick + 9;
bcable_t  = 1.7; // Grommet thickness
bcable_d1 = 5.4; // Rectangular hole X
bcable_d2 = 3.4; // Rectangular hole Y
bcable_r  = 1.5; // Chamfer radius

//-------------------------------------------------------------------------
// Housing for a rubber foot.
//-------------------------------------------------------------------------
module rubber_foot(d1, d2, h) {
    $fn = 48;
    difference() {
        cylinder(r=(d1 / 2), h=h);
        translate([0, 0, -overcut]) cylinder(r=(d2 / 2), h=(h + overcut * 2));
    }
}

//-------------------------------------------------------------------------
// Housings for rubber feet (grows towards negative z axis).
//-------------------------------------------------------------------------
module box_feet(x, y, margin) {
    d1 = 11.0;
    d2 =  8.2;
    h  =  0.8;
    translate([margin,     margin,     -h]) rubber_foot(d1, d2, h + overlap);
    translate([x - margin, margin,     -h]) rubber_foot(d1, d2, h + overlap);
    translate([x - margin, y - margin, -h]) rubber_foot(d1, d2, h + overlap);
    translate([margin,     y - margin, -h]) rubber_foot(d1, d2, h + overlap);
}

//-------------------------------------------------------------------------
// Flange for screw hole.
//-------------------------------------------------------------------------
module screw_flange(r, t) {
    $fn = 60;
    screw_diameter = 2.2;
    r1 = r * 1.1;
    difference() {
        intersection() {
            cylinder(r=r1, h=t);
            union() {
                translate([r, r, 0]) cylinder(r=r, h=t);
                translate([r, 0, 0]) cube([r, r, t]);
                translate([0, r, 0]) cube([r, r, t]);}}
        translate([r1 / 2, r1 / 2, -overcut]) cylinder(r=(screw_diameter * 0.75 / 2), h=(t + overcut * 2), $fn=24);
    }
}

//-------------------------------------------------------------------------
// Add a flange to the rounded_box() module.
//-------------------------------------------------------------------------
module rounded_box_flange(x, y, z, r) {
    w = 1.5;
    difference() {
        rounded_cube(x_size, y_size, z, r);
        translate([w, w, -overcut])
            rounded_cube(x_size - w * 2, y_size - w * 2, z + overcut * 2, r);
    }
    translate([0, 0, 0]) rotate(a=0 ,  v=[0, 0, 1]) screw_flange(r, z);
    translate([x, 0, 0]) rotate(a=90,  v=[0, 0, 1]) screw_flange(r, z);
    translate([x, y, 0]) rotate(a=180, v=[0, 0, 1]) screw_flange(r, z);
    translate([0, y, 0]) rotate(a=270, v=[0, 0, 1]) screw_flange(r, z);
}

//-------------------------------------------------------------------------
// Round cable grommet.
//-------------------------------------------------------------------------
module cable_grommet(h, d1, d2) {
    $fn = 32;
    cut_width = 3;
    difference() {
        union() {
            cylinder(r=(d1 / 2), h=h);
            translate([0, 0, h - 2.4]) cylinder(r=((d1 + 1.0) / 2), h=2.4);
        }
        translate([0, 0, -overcut]) cylinder(r=(d2 / 2), h=(h + 2 * overcut));
        translate([(d2 / 4), -(d1 / 2), h - (cut_width + 2.5)])
            cube([(d1 / 2), d1, cut_width]);
    }
}

//-------------------------------------------------------------------------
// Rectangular (with chamfer) cable grommet.
// h = height, x, y = hole inner size, r = chamfer radius, t = thickness
//-------------------------------------------------------------------------
module cable_grommet_rect(h, x, y, r, t) {
    cut_width = 3;
    difference() {
        union() {
            translate([-x / 2, -y / 2, 0]) rounded_cube_border(x, y, h, r, t);
            translate([-x / 2, -y / 2, h - 2.4]) rounded_cube_border(x, y, 2.4, r, t + 0.5);
        }
        translate([-(x / 2) - t - overcut, 0, h - (cut_width + 2.5)])
            cube([x + (t + overcut) * 2, y / 2 + t + overcut, cut_width]);
    }
}

//-------------------------------------------------------------------------
// Drill a screw hole with cuts for horizontal and vertical wall mount.
// Screw body diameter is d, head diameter will be d * 2.
//-------------------------------------------------------------------------
module screw_hole(d, depth) {
    $fn = 32;
    hole_depth = depth + overcut * 2;
    hole_bottom = -(depth + overcut);
    cut_length = d * 2;
    union() {
        translate([0, 0, hole_bottom])          cylinder(r=d, h=hole_depth);
        translate([-(d / 2), 0, hole_bottom])   cube([d, cut_length, hole_depth]);
        translate([0, -(d / 2), hole_bottom])   cube([cut_length, d, hole_depth]);
        translate([0, cut_length, hole_bottom]) cylinder(r=(d / 2), h=hole_depth);
        translate([cut_length, 0, hole_bottom]) cylinder(r=(d / 2), h=hole_depth);
    }
}

//-------------------------------------------------------------------------
// Build a cap to place over a screw hole.
// Screw body diameter = d
// Screw head diameter = d * 2
// Screw head height   = d * 0.6
//-------------------------------------------------------------------------
module screw_hole_cap(d, thick) {
    $fn = 36;
    r2 = 1.4142;
    pin_radius = thick * 1.3;
    pin_heigh = (d * 0.6) + (overlap * 2);
    pin_base = -overlap;
    offset = (((pin_radius * r2) - pin_radius) / r2) + ((pin_radius * 2) / r2) + (d / r2);
    size1 = (offset + overlap) * 2;
    size2 = size1 + d * 2;
    translate([-(size1 / 2), -(size1 / 2), 0]) {
        union() {
            translate([0, 0, d * 0.6]) rounded_cube(size1, size2, thick, pin_radius);
            translate([0, 0, d * 0.6]) rounded_cube(size2, size1, thick, pin_radius);
            translate([pin_radius, pin_radius, pin_base])                 cylinder(r=pin_radius, h=pin_heigh);
            translate([size2 - pin_radius, pin_radius, pin_base])         cylinder(r=pin_radius, h=pin_heigh);
            translate([size2 - pin_radius, size1 - pin_radius, pin_base]) cylinder(r=pin_radius, h=pin_heigh);
            translate([size1 - pin_radius, size2 - pin_radius, pin_base]) cylinder(r=pin_radius, h=pin_heigh);
            translate([pin_radius, size2 - pin_radius, pin_base])         cylinder(r=pin_radius, h=pin_heigh);
        }
    }
}

//-------------------------------------------------------------------------
// Make a box with the requested internal size and rounded corners.
// The origin is the lower-left internal corner.
//-------------------------------------------------------------------------
module rounded_box(x_size, y_size, z_size, chamfer, thick) {
    cover_thick = 2;
    union() {
        translate([-overlap, -overlap, -thick])
            rounded_cube(x_size + overlap * 2, y_size + overlap * 2, thick, chamfer + overlap);
        translate([0, 0, -thick])
            rounded_cube_border(x_size, y_size, z_size + thick, chamfer, thick);
        translate([-overlap, -overlap, z_size - cover_thick - thick])
            rounded_box_flange(x_size + overlap * 2, y_size + overlap * 2, thick, chamfer + overlap);
        translate([0, 0, -thick])
            box_feet(x_size, y_size, 10);
        // Draw the box cover, for dimension testing.
        //translate([0, 0, z_size - cover_thick])
        //    %rounded_cube(x_size, y_size, cover_thick, chamfer);
    }
}

//-------------------------------------------------------------------------
// Make a box with rounded corners, drill all the required holes.
//-------------------------------------------------------------------------
module rounded_box_holes(x_size, y_size, z_size, chamfer, thick) {

    holes_diam = 3.5;

    // Boiler cable grommet.
    translate([bcable_x, bcable_y, bcable_z])
        rotate(a=180, v=[0, 1, 0])
            rotate(a=270, v=[1, 0, 0])
                cable_grommet_rect(bcable_h, bcable_d1, bcable_d2, bcable_r, bcable_t);

    // Temperature sensor cable grommet.
    translate([tsensor_x, tsensor_y, tsensor_z])
        rotate(a=90, v=[1, 0, 0])
            rotate(a=90, v=[0, 1, 0])
                cable_grommet(tsensor_h, tsensor_d1, tsensor_d2);

    difference() {
        rounded_box(x_size, y_size, z_size, chamfer, thick);

        // Bottom venting holes.
        translate([x_size / 2, 0, z_size / 2])
            rotate(a=90, v=[1, 0, 0]) vent_holes(12, 3, holes_diam, thick);

        // Top venting holes.
        translate([x_size / 2, y_size + thick, z_size / 2])
            rotate(a=90, v=[1, 0, 0]) vent_holes(11, 3, holes_diam, thick);

        // Backplane venting holes.
        translate([83, 88, -thick]) vent_holes(8, 6, holes_diam, thick);
        translate([25, 38, -thick]) vent_holes(5, 4, holes_diam, thick);

        // Mounting screw holes.
        translate([x_size / 2, screw_hole1_y, 0]) rotate(a=90, v=[0, 0, 1]) screw_hole(screw_diam, thick);
        translate([x_size / 2, screw_hole2_y, 0]) rotate(a=90, v=[0, 0, 1]) screw_hole(screw_diam, thick);

        // Temperature sensor hole.
        translate([-(thick + overcut), tsensor_y, tsensor_z])
            rotate(a=90, v=[0, 1, 0]) cylinder(r=(tsensor_d2 / 2), h=(thick + overcut * 2), $fn=24);

        // Push-button hole.
        translate([button_x - overcut, button_y, button_z])
            rotate(a=90, v=[0, 1, 0]) cylinder(r=(button_d / 2), h=(thick + overcut * 2), $fn=24);

        // Power socket hole.
        translate([psocket_x, overcut, psocket_z])
            rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2), h=(thick + overcut * 2), $fn=24);

        // Boiler cable hole.
        translate([bcable_x, bcable_y - overcut, bcable_z])
            rotate(a=270, v=[1, 0, 0]) rounded_cube_centered(bcable_d1, bcable_d2, bcable_h + overcut * 2, bcable_r);

    }

    // Reinforce for power socket hole.
    difference() {
        translate([psocket_x, 0, psocket_z]) rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2) + 2.5, h=thick);
        translate([psocket_x, overcut, psocket_z])
            rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2), h=(thick + overcut * 2), $fn=24);
    }

    // Reinforce for boiler cable hole.
    difference() {
        translate([bcable_x, 0, bcable_z])
            rotate(a=90, v=[1, 0, 0]) rounded_cube_centered(bcable_d1 + 5.5, bcable_d2 + 5.5, thick, 3);
        translate([bcable_x, overcut, bcable_z])
            rotate(a=90, v=[1, 0, 0]) rounded_cube_centered(bcable_d1, bcable_d2, (thick + overcut * 2), bcable_r);
    }

    // Mounting screws holes.
    translate([x_size / 2, screw_hole1_y, 0]) rotate(a=90, v=[0, 0, 1]) #screw_hole_cap(screw_diam, 1.7);
    translate([x_size / 2, screw_hole2_y, 0]) rotate(a=90, v=[0, 0, 1]) #screw_hole_cap(screw_diam, 1.7);
}

//-------------------------------------------------------------------------
// Drill a grid of rows x columns vent holes. Each hole has the
// specified diameter and depth, the grid is centered into the origin.
//-------------------------------------------------------------------------
module vent_holes(x, y, diameter, depth) {
    $fn = 6; // 18 = rounded holes, 6 = hexagonal
    step = diameter * 2;
    radius = diameter / 1.8;  // Divide by 2.0 if rounded holes, 1.8 if hexagonal.
    offset_x = (step * (x - 1)) / 2;
    offset_y = (step * (y - 1)) / 2;
    for (i = [1:x]) {
        for (j = [1:y]) {
            translate([(i - 1) * step - offset_x, (j -1) * step - offset_y, -overcut])
              cylinder(r=radius, h=(depth + overcut * 2));
        }
    }
    for (i = [1:x-1]) {
        for (j = [1:y-1]) {
            translate([(i - 1) * step - offset_x + step / 2, (j -1) * step - offset_y + step / 2, -overcut])
                cylinder(r=radius, h=(depth + overcut * 2));
        }
    }
}

//-------------------------------------------------------------------------
// Screw stub: d1 is the outer diameter, d2 is the screw diameter.
// The stub height must be grather than the depth of the hole.
//-------------------------------------------------------------------------
module stub(d1, height, d2, hole_depth) {
    $fn = 36;
    // The hole for a self-tapping screw is narrower than the screw.
    hole_diameter = d2 * 0.75;
    difference() {
        translate([0, 0, -overlap]) {
            union() {
                cylinder(r=(d1 / 2), h=(height + overlap));
                cylinder(r1=(d1 * 0.7), r2=(d1 / 2), h=(4 + overlap));
            }
        }
        translate([0, 0, height - hole_depth])
            cylinder(r=(hole_diameter / 2), h=(hole_depth + overcut));
    }
}

//-------------------------------------------------------------------------
// Screw stubs for relay board (SainSmart like manufacturer).
//-------------------------------------------------------------------------
module stubs_2relays_sainsmart(height) {
    diameter = 7;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([2.75, 2.75, 0]) {
        translate([ 0,      0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([33.5,    0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,    45.5, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([33.5, 45.5, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for relay board (Keyes manufacturer).
//-------------------------------------------------------------------------
module stubs_2relays_keyes(height) {
    diameter = 7;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([3.5, 9, 0]) {
        translate([ 0,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([38,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,  40, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([38, 40, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for PCD8544 LCD (Nokia 5110/3310), blue PCB model.
//-------------------------------------------------------------------------
module stubs_pcd8544_blue(height) {
    diameter = 6.5;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([4.25, 2.25, 0]) {
        translate([ 0,    0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([34.5,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,    41, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([34.5, 41, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for PCD8544 LCD (Nokia 5110/3310), red PCB model.
//-------------------------------------------------------------------------
module stubs_pcd8544_red(height) {
    diameter = 6.0;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([1.75, 2.0, 0]) {
        translate([ 0,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([40,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([ 0, 39, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([40, 39, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for Raspberry Pi Model B v.2.
//-------------------------------------------------------------------------
module stubs_raspberrypi_model_b_v2(height) {
    screw_diameter = 2.2;
    hole_depth = 6;
    translate([38, 25.5, 0]) {
        translate([    0,    0, 0]) stub(6.5, height, screw_diameter, hole_depth);
        translate([-25.5, 54.5, 0]) stub(6.5, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Main procedure.
//-------------------------------------------------------------------------
translate([-(x_size / 2), -(y_size/2), 0]) {
    rounded_box_holes(x_size, y_size, z_size, chamfer, thick);
    translate([ 5, 12,  0.0]) stubs_2relays_sainsmart(5.0);
    translate([ 8, 90,  0.0]) stubs_pcd8544_red(20.5); // Non diminuire Y sennò tocca il coprivite!
    translate([55, 37,  0.0]) stubs_raspberrypi_model_b_v2(5.0);
    //translate([55, 37 , 5.0]) board_raspberrypi_model_b_v2();
    //translate([ 8, 90, 20.5]) board_pcd8544_red();
    //translate([ 5, 12,  5.0]) board_2relays_sainsmart();
    //translate([button_x, button_y, button_z]) rotate(a=90, v=[0, 1, 0]) push_button();
    //translate([psocket_x, -thick, psocket_z]) rotate(a=90, v=[1, 0, 0]) coax_power_jack();
}

include <RigacciOrg.scad>;
translate([-x_size / 2 - thick + overlap, -29, 13])
    rotate(a=270, v=[0,0,1]) rotate(a=90, v=[1,0,0]) {
        //#cube([55, 12.54, 0.5], center=true);
        RigacciOrg(0.5);
    }

include <ccbysa.scad>;
translate([-x_size / 2 - thick + overlap, 34, 13])
    rotate(a=270, v=[0,0,1]) rotate(a=90, v=[1,0,0]) {
        //#cube([35.60, 12.54, 0.5], center=true);
        ccbysa(0.5);
    }

//-------------------------------------------------------------------------
// The cover: 2D shape for laser cutting. Load this geometry alone,
// Compile and Render (F6), Export to DXF (protherm-2d-cover.dxf).
//
// Nominal size on the X axis:
//
//   x_size - overcut * 2   =>   115.0 - 0.1 * 2 = 114.8
//
// The cutted real piece turned out to be 114.5 mm, then we suppose
// that the laser track on plexiglass is about 0.3 mm.
//-------------------------------------------------------------------------
screw_diameter = 2.5;
r1 = (chamfer - overcut) * 1.1;
x = x_size + overlap * 2;
y = y_size + overlap * 2;
translate([-(x_size / 2), -(y_size/2)]) {
    difference() {
      rounded_square(x_size - (overcut * 2), y_size - (overcut * 2), (chamfer - overcut));
      union() {
          translate([0, 0]) rotate(a=0 ,   v=[0, 0, 1]) translate([r1 / 2, r1 / 2]) circle(r=(screw_diameter / 2), $fn=24);
          translate([x, 0]) rotate(a=90,   v=[0, 0, 1]) translate([r1 / 2, r1 / 2]) circle(r=(screw_diameter / 2), $fn=24);
          translate([x, y]) rotate(a=180,  v=[0, 0, 1]) translate([r1 / 2, r1 / 2]) circle(r=(screw_diameter / 2), $fn=24);
          translate([0, y]) rotate(a=270,  v=[0, 0, 1]) translate([r1 / 2, r1 / 2]) circle(r=(screw_diameter / 2), $fn=24);
      }
    }
}

//See:
// http://edutechwiki.unige.ch/en/OpenScad_beginners_tutorial
// https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/

// Global variables.
overcut = 0.1;  // Overcut for solid difference(), to assure complete holes.
overlap = 0.1;  // Intersection for solid union() to avoid the manifold problem.

include <misc_parts.scad>;
include <boards.scad>;
include <rounded_cube.scad>;

// Box internal size.
x_size  = 115.0;
y_size  = 144.0;
z_size  =  29.0;
thick   =   2.2;
chamfer =  13.0;

// Mounting screw holes.
screw_hole1_y = 24;
screw_hole2_y = y_size - 26;
screw_diam    = 3.6;

// Position and size of push button hole.
button_x = x_size;
button_y = 64;
button_z = 16.0;
button_d = 6.4;

// Position and size of power socket hole.
psocket_x = x_size / 2;
psocket_z = 7;
psocket_d = 8.2;

// Position and size for temperature sensor grommet.
tsensor_x  = -thick - 1;
tsensor_y  = 78;
tsensor_z  = 13;
tsensor_h  = thick + 9;
tsensor_d1 = 9.0;
tsensor_d2 = 5.5;

// Positon and size for boiler cable grommet (cable is 5.5 x 3.5 mm).
bcable_x  = 19;
bcable_y  = -thick - 1;
bcable_z  = 9.5;
bcable_h  = thick + 9;
bcable_t  = 1.7; // Grommet thickness
bcable_d1 = 5.4; // Rectangular hole X
bcable_d2 = 3.4; // Rectangular hole Y
bcable_r  = 1.5; // Chamfer radius

//-------------------------------------------------------------------------
// Housing for a rubber foot.
//-------------------------------------------------------------------------
module rubber_foot(d1, d2, h) {
    $fn = 48;
    difference() {
        cylinder(r=(d1 / 2), h=h);
        translate([0, 0, -overcut]) cylinder(r=(d2 / 2), h=(h + overcut * 2));
    }
}

//-------------------------------------------------------------------------
// Housings for rubber feet (grows towards negative z axis).
//-------------------------------------------------------------------------
module box_feet(x, y, margin) {
    d1 = 11.0;
    d2 =  8.2;
    h  =  0.8;
    translate([margin,     margin,     -h]) rubber_foot(d1, d2, h + overlap);
    translate([x - margin, margin,     -h]) rubber_foot(d1, d2, h + overlap);
    translate([x - margin, y - margin, -h]) rubber_foot(d1, d2, h + overlap);
    translate([margin,     y - margin, -h]) rubber_foot(d1, d2, h + overlap);
}

//-------------------------------------------------------------------------
// Flange for screw hole.
//-------------------------------------------------------------------------
module screw_flange(r, t) {
    $fn = 60;
    screw_diameter = 2.2;
    r1 = r * 1.1;
    difference() {
        intersection() {
            cylinder(r=r1, h=t);
            union() {
                translate([r, r, 0]) cylinder(r=r, h=t);
                translate([r, 0, 0]) cube([r, r, t]);
                translate([0, r, 0]) cube([r, r, t]);}}
        translate([r1 / 2, r1 / 2, -overcut]) cylinder(r=(screw_diameter * 0.75 / 2), h=(t + overcut * 2), $fn=24);
    }
}

//-------------------------------------------------------------------------
// Add a flange to the rounded_box() module.
//-------------------------------------------------------------------------
module rounded_box_flange(x, y, z, r) {
    w = 1.5;
    difference() {
        rounded_cube(x_size, y_size, z, r);
        translate([w, w, -overcut])
            rounded_cube(x_size - w * 2, y_size - w * 2, z + overcut * 2, r);
    }
    translate([0, 0, 0]) rotate(a=0 ,  v=[0, 0, 1]) screw_flange(r, z);
    translate([x, 0, 0]) rotate(a=90,  v=[0, 0, 1]) screw_flange(r, z);
    translate([x, y, 0]) rotate(a=180, v=[0, 0, 1]) screw_flange(r, z);
    translate([0, y, 0]) rotate(a=270, v=[0, 0, 1]) screw_flange(r, z);
}

//-------------------------------------------------------------------------
// Round cable grommet.
//-------------------------------------------------------------------------
module cable_grommet(h, d1, d2) {
    $fn = 32;
    cut_width = 3;
    difference() {
        union() {
            cylinder(r=(d1 / 2), h=h);
            translate([0, 0, h - 2.4]) cylinder(r=((d1 + 1.0) / 2), h=2.4);
        }
        translate([0, 0, -overcut]) cylinder(r=(d2 / 2), h=(h + 2 * overcut));
        translate([(d2 / 4), -(d1 / 2), h - (cut_width + 2.5)])
            cube([(d1 / 2), d1, cut_width]);
    }
}

//-------------------------------------------------------------------------
// Rectangular (with chamfer) cable grommet.
// h = height, x, y = hole inner size, r = chamfer radius, t = thickness
//-------------------------------------------------------------------------
module cable_grommet_rect(h, x, y, r, t) {
    cut_width = 3;
    difference() {
        union() {
            translate([-x / 2, -y / 2, 0]) rounded_cube_border(x, y, h, r, t);
            translate([-x / 2, -y / 2, h - 2.4]) rounded_cube_border(x, y, 2.4, r, t + 0.5);
        }
        translate([-(x / 2) - t - overcut, 0, h - (cut_width + 2.5)])
            cube([x + (t + overcut) * 2, y / 2 + t + overcut, cut_width]);
    }
}

//-------------------------------------------------------------------------
// Drill a screw hole with cuts for horizontal and vertical wall mount.
// Screw body diameter is d, head diameter will be d * 2.
//-------------------------------------------------------------------------
module screw_hole(d, depth) {
    $fn = 32;
    hole_depth = depth + overcut * 2;
    hole_bottom = -(depth + overcut);
    cut_length = d * 2;
    union() {
        translate([0, 0, hole_bottom])          cylinder(r=d, h=hole_depth);
        translate([-(d / 2), 0, hole_bottom])   cube([d, cut_length, hole_depth]);
        translate([0, -(d / 2), hole_bottom])   cube([cut_length, d, hole_depth]);
        translate([0, cut_length, hole_bottom]) cylinder(r=(d / 2), h=hole_depth);
        translate([cut_length, 0, hole_bottom]) cylinder(r=(d / 2), h=hole_depth);
    }
}

//-------------------------------------------------------------------------
// Build a cap to place over a screw hole.
// Screw body diameter = d
// Screw head diameter = d * 2
// Screw head height   = d * 0.6
//-------------------------------------------------------------------------
module screw_hole_cap(d, thick) {
    $fn = 36;
    r2 = 1.4142;
    pin_radius = thick * 1.3;
    pin_heigh = (d * 0.6) + (overlap * 2);
    pin_base = -overlap;
    offset = (((pin_radius * r2) - pin_radius) / r2) + ((pin_radius * 2) / r2) + (d / r2);
    size1 = (offset + overlap) * 2;
    size2 = size1 + d * 2;
    translate([-(size1 / 2), -(size1 / 2), 0]) {
        union() {
            translate([0, 0, d * 0.6]) rounded_cube(size1, size2, thick, pin_radius);
            translate([0, 0, d * 0.6]) rounded_cube(size2, size1, thick, pin_radius);
            translate([pin_radius, pin_radius, pin_base])                 cylinder(r=pin_radius, h=pin_heigh);
            translate([size2 - pin_radius, pin_radius, pin_base])         cylinder(r=pin_radius, h=pin_heigh);
            translate([size2 - pin_radius, size1 - pin_radius, pin_base]) cylinder(r=pin_radius, h=pin_heigh);
            translate([size1 - pin_radius, size2 - pin_radius, pin_base]) cylinder(r=pin_radius, h=pin_heigh);
            translate([pin_radius, size2 - pin_radius, pin_base])         cylinder(r=pin_radius, h=pin_heigh);
        }
    }
}

//-------------------------------------------------------------------------
// Make a box with the requested internal size and rounded corners.
// The origin is the lower-left internal corner.
//-------------------------------------------------------------------------
module rounded_box(x_size, y_size, z_size, chamfer, thick) {
    cover_thick = 2;
    union() {
        translate([-overlap, -overlap, -thick])
            rounded_cube(x_size + overlap * 2, y_size + overlap * 2, thick, chamfer + overlap);
        translate([0, 0, -thick])
            rounded_cube_border(x_size, y_size, z_size + thick, chamfer, thick);
        translate([-overlap, -overlap, z_size - cover_thick - thick])
            rounded_box_flange(x_size + overlap * 2, y_size + overlap * 2, thick, chamfer + overlap);
        translate([0, 0, -thick])
            box_feet(x_size, y_size, 10);
        // Draw the box cover, for dimension testing.
        //translate([0, 0, z_size - cover_thick])
        //    %rounded_cube(x_size, y_size, cover_thick, chamfer);
    }
}

//-------------------------------------------------------------------------
// Make a box with rounded corners, drill all the required holes.
//-------------------------------------------------------------------------
module rounded_box_holes(x_size, y_size, z_size, chamfer, thick) {

    holes_diam = 3.5;

    // Boiler cable grommet.
    translate([bcable_x, bcable_y, bcable_z])
        rotate(a=180, v=[0, 1, 0])
            rotate(a=270, v=[1, 0, 0])
                cable_grommet_rect(bcable_h, bcable_d1, bcable_d2, bcable_r, bcable_t);

    // Temperature sensor cable grommet.
    translate([tsensor_x, tsensor_y, tsensor_z])
        rotate(a=90, v=[1, 0, 0])
            rotate(a=90, v=[0, 1, 0])
                cable_grommet(tsensor_h, tsensor_d1, tsensor_d2);

    difference() {
        rounded_box(x_size, y_size, z_size, chamfer, thick);

        // Bottom venting holes.
        translate([x_size / 2, 0, z_size / 2])
            rotate(a=90, v=[1, 0, 0]) vent_holes(12, 3, holes_diam, thick);

        // Top venting holes.
        translate([x_size / 2, y_size + thick, z_size / 2])
            rotate(a=90, v=[1, 0, 0]) vent_holes(11, 3, holes_diam, thick);

        // Backplane venting holes.
        translate([83, 88, -thick]) vent_holes(8, 6, holes_diam, thick);
        translate([25, 38, -thick]) vent_holes(5, 4, holes_diam, thick);

        // Mounting screw holes.
        translate([x_size / 2, screw_hole1_y, 0]) rotate(a=90, v=[0, 0, 1]) screw_hole(screw_diam, thick);
        translate([x_size / 2, screw_hole2_y, 0]) rotate(a=90, v=[0, 0, 1]) screw_hole(screw_diam, thick);

        // Temperature sensor hole.
        translate([-(thick + overcut), tsensor_y, tsensor_z])
            rotate(a=90, v=[0, 1, 0]) cylinder(r=(tsensor_d2 / 2), h=(thick + overcut * 2), $fn=24);

        // Push-button hole.
        translate([button_x - overcut, button_y, button_z])
            rotate(a=90, v=[0, 1, 0]) cylinder(r=(button_d / 2), h=(thick + overcut * 2), $fn=24);

        // Power socket hole.
        translate([psocket_x, overcut, psocket_z])
            rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2), h=(thick + overcut * 2), $fn=24);

        // Boiler cable hole.
        translate([bcable_x, bcable_y - overcut, bcable_z])
            rotate(a=270, v=[1, 0, 0]) rounded_cube_centered(bcable_d1, bcable_d2, bcable_h + overcut * 2, bcable_r);

    }

    // Reinforce for power socket hole.
    difference() {
        translate([psocket_x, 0, psocket_z]) rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2) + 2.5, h=thick);
        translate([psocket_x, overcut, psocket_z])
            rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2), h=(thick + overcut * 2), $fn=24);
    }

    // Reinforce for boiler cable hole.
    difference() {
        translate([bcable_x, 0, bcable_z])
            rotate(a=90, v=[1, 0, 0]) rounded_cube_centered(bcable_d1 + 5.5, bcable_d2 + 5.5, thick, 3);
        translate([bcable_x, overcut, bcable_z])
            rotate(a=90, v=[1, 0, 0]) rounded_cube_centered(bcable_d1, bcable_d2, (thick + overcut * 2), bcable_r);
    }

    // Mounting screws holes.
    translate([x_size / 2, screw_hole1_y, 0]) rotate(a=90, v=[0, 0, 1]) #screw_hole_cap(screw_diam, 1.7);
    translate([x_size / 2, screw_hole2_y, 0]) rotate(a=90, v=[0, 0, 1]) #screw_hole_cap(screw_diam, 1.7);
}

//-------------------------------------------------------------------------
// Drill a grid of rows x columns vent holes. Each hole has the
// specified diameter and depth, the grid is centered into the origin.
//-------------------------------------------------------------------------
module vent_holes(x, y, diameter, depth) {
    $fn = 6; // 18 = rounded holes, 6 = hexagonal
    step = diameter * 2;
    radius = diameter / 1.8;  // Divide by 2.0 if rounded holes, 1.8 if hexagonal.
    offset_x = (step * (x - 1)) / 2;
    offset_y = (step * (y - 1)) / 2;
    for (i = [1:x]) {
        for (j = [1:y]) {
            translate([(i - 1) * step - offset_x, (j -1) * step - offset_y, -overcut])
              cylinder(r=radius, h=(depth + overcut * 2));
        }
    }
    for (i = [1:x-1]) {
        for (j = [1:y-1]) {
            translate([(i - 1) * step - offset_x + step / 2, (j -1) * step - offset_y + step / 2, -overcut])
                cylinder(r=radius, h=(depth + overcut * 2));
        }
    }
}

//-------------------------------------------------------------------------
// Screw stub: d1 is the outer diameter, d2 is the screw diameter.
// The stub height must be grather than the depth of the hole.
//-------------------------------------------------------------------------
module stub(d1, height, d2, hole_depth) {
    $fn = 36;
    // The hole for a self-tapping screw is narrower than the screw.
    hole_diameter = d2 * 0.75;
    difference() {
        translate([0, 0, -overlap]) {
            union() {
                cylinder(r=(d1 / 2), h=(height + overlap));
                cylinder(r1=(d1 * 0.7), r2=(d1 / 2), h=(4 + overlap));
            }
        }
        translate([0, 0, height - hole_depth])
            cylinder(r=(hole_diameter / 2), h=(hole_depth + overcut));
    }
}

//-------------------------------------------------------------------------
// Screw stubs for relay board (SainSmart like manufacturer).
//-------------------------------------------------------------------------
module stubs_2relays_sainsmart(height) {
    diameter = 7;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([2.75, 2.75, 0]) {
        translate([ 0,      0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([33.5,    0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,    45.5, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([33.5, 45.5, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for relay board (Keyes manufacturer).
//-------------------------------------------------------------------------
module stubs_2relays_keyes(height) {
    diameter = 7;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([3.5, 9, 0]) {
        translate([ 0,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([38,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,  40, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([38, 40, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for PCD8544 LCD (Nokia 5110/3310), blue PCB model.
//-------------------------------------------------------------------------
module stubs_pcd8544_blue(height) {
    diameter = 6.5;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([4.25, 2.25, 0]) {
        translate([ 0,    0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([34.5,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,    41, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([34.5, 41, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for PCD8544 LCD (Nokia 5110/3310), red PCB model.
//-------------------------------------------------------------------------
module stubs_pcd8544_red(height) {
    diameter = 6.0;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([1.75, 2.0, 0]) {
        translate([ 0,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([40,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([ 0, 39, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([40, 39, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for Raspberry Pi Model B v.2.
//-------------------------------------------------------------------------
module stubs_raspberrypi_model_b_v2(height) {
    screw_diameter = 2.2;
    hole_depth = 6;
    translate([38, 25.5, 0]) {
        translate([    0,    0, 0]) stub(6.5, height, screw_diameter, hole_depth);
        translate([-25.5, 54.5, 0]) stub(6.5, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Main procedure.
//-------------------------------------------------------------------------
translate([-(x_size / 2), -(y_size/2), 0]) {
    rounded_box_holes(x_size, y_size, z_size, chamfer, thick);
    translate([ 5, 12,  0.0]) stubs_2relays_sainsmart(5.0);
    translate([ 8, 90,  0.0]) stubs_pcd8544_red(20.5); // Non diminuire Y sennò tocca il coprivite!
    translate([55, 37,  0.0]) stubs_raspberrypi_model_b_v2(5.0);
    //translate([55, 37 , 5.0]) board_raspberrypi_model_b_v2();
    //translate([ 8, 90, 20.5]) board_pcd8544_red();
    //translate([ 5, 12,  5.0]) board_2relays_sainsmart();
    //translate([button_x, button_y, button_z]) rotate(a=90, v=[0, 1, 0]) push_button();
    //translate([psocket_x, -thick, psocket_z]) rotate(a=90, v=[1, 0, 0]) coax_power_jack();
}

include <RigacciOrg.scad>;
translate([-x_size / 2 - thick + overlap, -29, 13])
    rotate(a=270, v=[0,0,1]) rotate(a=90, v=[1,0,0]) {
        //#cube([55, 12.54, 0.5], center=true);
        RigacciOrg(0.5);
    }

include <ccbysa.scad>;
translate([-x_size / 2 - thick + overlap, 34, 13])
    rotate(a=270, v=[0,0,1]) rotate(a=90, v=[1,0,0]) {
        //#cube([35.60, 12.54, 0.5], center=true);
        ccbysa(0.5);
    }

//-------------------------------------------------------------------------
// 2D Cover: load this geometry alone, Compile and Render (F6),
// Export to DXF (protherm-2d-cover.dxf).
//-------------------------------------------------------------------------
screw_diameter = 2.5;
r1 = (chamfer - overcut) * 1.1;
x = x_size + overlap * 2;
y = y_size + overlap * 2;
translate([-(x_size / 2), -(y_size/2)]) {
    difference() {
      rounded_square(x_size - (overcut * 2), y_size - (overcut * 2), (chamfer - overcut));
      union() {
          translate([0, 0]) rotate(a=0 ,   v=[0, 0, 1]) translate([r1 / 2, r1 / 2]) circle(r=(screw_diameter / 2), $fn=24);
          translate([x, 0]) rotate(a=90,   v=[0, 0, 1]) translate([r1 / 2, r1 / 2]) circle(r=(screw_diameter / 2), $fn=24);
          translate([x, y]) rotate(a=180,  v=[0, 0, 1]) translate([r1 / 2, r1 / 2]) circle(r=(screw_diameter / 2), $fn=24);
          translate([0, y]) rotate(a=270,  v=[0, 0, 1]) translate([r1 / 2, r1 / 2]) circle(r=(screw_diameter / 2), $fn=24);
      }
    }
}


Changing roof

Changing roof

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*2,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 sheetFramed(size,center=false, f_timber_width=0, f_timber_length=0, f_offset_w_l=0, f_offset_w_r=0, f_offset_l=0)
{
    cubeI(size, center=center);
    if(f_timber_width>0) // Panel is Not longer than width
    {
        translate([f_offset_w_l,f_offset_l,-f_timber_length]) cubeI([size[0]-f_offset_w_l-f_offset_w_r, f_timber_width, f_timber_length]);
        translate([f_offset_w_l,size[1]-f_timber_width-f_offset_l,-f_timber_length]) cubeI([size[0]-f_offset_w_l-f_offset_w_r, f_timber_width, f_timber_length]);
        translate([f_offset_w_l,f_offset_l+f_timber_width,-f_timber_length]) cubeI([f_timber_width, size[1]-f_offset_l*2-f_timber_width*2, f_timber_length]);
      translate([size[0]-f_timber_width-f_offset_w_r,f_offset_l+f_timber_width,-f_timber_length]) cubeI([f_timber_width, size[1]-f_offset_l*2-f_timber_width*2, f_timber_length]);
        }
}

module shedLowerFloor(x,y, panel_slf_w = 1220, panel_slf_l = 2440, panel_slf_t = base_sheet_t, panel_min_dimentions = 100, f_timber_width=0,f_timber_length=0, f_offset_l=0)
{
//    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])
            {
                // f_offset_w_l=0, f_offset_w_r=0
                 f_offset_w_l_ =   base_x==0 ? f_offset_l +timber_construct_w/2+3: 0;
                translate([base_x*panel_slf_w,base_y*panel_slf_l,0]) sheetFramed([panel_slf_w, panel_slf_l,panel_slf_t], f_timber_width=f_timber_width, f_timber_length=f_timber_length, f_offset_l=f_offset_l, f_offset_w_l=f_offset_w_l_);
                if(y-(panel_slf_l*y_panels) > panel_min_dimentions)
                translate([base_x*panel_slf_w,y_panels*panel_slf_l,0]) sheetFramed([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]) sheetFramed([x-(panel_slf_w*x_panels), panel_slf_l,panel_slf_t], f_timber_width=f_timber_width, f_timber_length=f_timber_length, f_offset_l=f_offset_l, f_offset_w_r=f_offset_l +timber_construct_w/2+3);
            if(y-(panel_slf_l*y_panels) > panel_min_dimentions)
                translate([(x_panels)*panel_slf_w,y_panels*panel_slf_l,0]) sheetFramed([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]) sheetFramed([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]) sheetFramed([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("Struts - http://www.wickes.co.uk/Wickes-Studwork-%28CLS%29-38x63x2400mm-Single/p/107177");
    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)
{
    echo("Cladding: ", board_height, x);
    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 = 34, degrees=3)
{
    echo("Cladding Total:", x, z);
    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*2]);
    }
}

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*2]);
    }
}

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])
    {
        translate([0,timber_construct_h/2,0]) shedLowerFloor(x+overhang_flat*2,panel_slf_l, f_timber_width=75, f_timber_length=47, f_offset_l=overhang_flat-base_timber/2);
//        translate([overhang,overhang,0]) roofJoists(x,y+17.5,7 );
    }
}

module insulate(space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h, thickness=50, colour="White", off=0)
{
    translate([thickness,shed_width-thickness-off,0]) color(colour,0.5) cube([shed_length-thickness*2, thickness, shed_front_back]);

    opp = shed_front_height-shed_front_back;
    adj = shed_width - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    echo("Degrees: ", theta);
    translate([0,0,0]) rotate([0,0,90]) difference()
    {
        translate([thickness,-thickness-off,0]) color(colour,0.5) cube([shed_width-thickness*2, thickness, shed_front_height]);
        translate([0,-opp/2-off,shed_front_height]) rotate([0,theta,0]) cube([shed_width+10,opp,opp*2]);
    }
    translate([shed_length-thickness-off,0,0]) rotate([0,0,90]) difference()
    {
        translate([thickness,-thickness,0]) color(colour,0.5) cube([shed_width-thickness*2, thickness, shed_front_height]);
        translate([0,-opp/2,shed_front_height]) rotate([0,theta,0]) cube([shed_width+10,opp,opp*2]);
    }

    translate([0,off,0]) rotate([0,0,0]) difference()
    {
    translate([thickness,0,0]) color(colour,0.5) cube([shed_length-thickness*2, thickness, shed_front_height]);
        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 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;

//rotate([6.34182+180,0,0])
//    {

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-base_timber-1, 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-base_timber-3,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-base_timber-3,2, braces=1);

if($t>annimate_step*7)
    translate([0,0,base_timber+1+base_sheet_t])  frontWallStruts(shed_length,shed_front_height-base_timber-3, 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.51,base_timber])
        breatherMembrane(shed_length, shed_front_back);

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

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

if($t>annimate_step*12)
    translate([0,-0.5,timber_construct_h])
        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,timber_construct_h])
        claddingBackWall(shed_length, shed_front_back);

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

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

if($t>annimate_step*16)
    translate([-3,0,timber_construct_h])
        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);

if($t>annimate_step*17)
    translate([0,0,timber_construct_h])
        insulate(space_to_window_w=1830/2, space_to_window_h=2030-610, window_w=1830, window_h=610, door_w=870, door_h=2030);

if($t>annimate_step*18)
    translate([0,0,timber_construct_h])
        insulate(space_to_window_w=1830/2, space_to_window_h=2030-610, window_w=1830, window_h=610, door_w=870, door_h=2030, thickness=5, colour="Black", off=timber_construct_h);

//restOfGarden();

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 = 34, 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 insulate(space_to_window_w, space_to_window_h, window_w, window_h, door_w, door_h, thickness=50, colour="White")
{
    translate([0,shed_width-thickness,0]) color(colour,0.5) cube([shed_length, thickness, shed_front_back]);

    opp = shed_front_height-shed_front_back;
    adj = shed_width - base_timber;
    hyp = sqrt(opp*opp+adj*adj);
    theta = atan(opp/adj);
    echo("Degrees: ", theta);
    translate([0,0,0]) rotate([0,0,90]) difference()
    {
        translate([0,-thickness,0]) color(colour,0.5) cube([shed_width, thickness, shed_front_back]);
        translate([0,-opp/2,shed_front_height]) rotate([0,theta,0]) cube([shed_width+10,opp,opp]);
    }
    translate([shed_length-thickness,0,0]) rotate([0,0,90]) difference()
    {
        translate([0,-thickness,0]) color(colour,0.5) cube([shed_width, thickness, shed_front_back]);
        translate([0,-opp/2,shed_front_height]) rotate([0,theta,0]) cube([shed_width+10,opp,opp]);
    }

    translate([0,0,0]) rotate([0,0,0]) difference()
    {
    translate([0,0,0]) color(colour,0.5) cube([shed_length, thickness, shed_front_height]);
        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 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.51,base_timber])
        breatherMembrane(shed_length, shed_front_back);

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

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

if($t>annimate_step*12)
    translate([0,-0.5,timber_construct_h])
        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,timber_construct_h])
        claddingBackWall(shed_length, shed_front_back);

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

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

if($t>annimate_step*16)
    translate([-3,0,timber_construct_h])
        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);

if($t>annimate_step*16)
    translate([0,0,timber_construct_h])
        insulate(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();


Added pyssla/perler bases

Added pyssla/perler bases

draft = true;
$fa = draft ? 12 : 3;
$fs = draft ? 2 : 0.1;
pin_fn = draft ? 12 : 24;

pin_height = 2.8;
pin_distance = 5;
pin_dia = 2.3;
base_height = 2;

board_type = "circle";
n = 8;

thing(board_type, n);

module thing(board_type, n) {
  if (board_type == "circle") circle_board(n);
  if (board_type == "square") rectangular_board(n,n);
  if (board_type == "heart") heart_board(n);
  if (board_type == "triangle") triangle_board(n);
  if (board_type == "hexagon") hexagon_board(n);
  if (board_type == "star") star_board(n);
}

module pin() {
  round_d=pin_dia/2;
  intersection() {
    minkowski() {
      translate([0,0,0]) cylinder(d=pin_dia-round_d,h=pin_height-round_d/2,$fn=pin_fn);
      sphere(d=round_d,$fn=pin_fn);
    }
    cylinder(d=pin_dia*2,h=pin_height,$fn=pin_fn);
  }
}

module circle_board(n=8) {
  module pins() {
    pin();
    for(i=[1:1:n]) {
      r = i*pin_distance;
      c = i*6;
      for(a=[0:360/c:359]) {
        rotate([0,0,a]) translate([r,0,0]) pin();
      }
    }
  }
  translate([0,0,base_height-0.01]) pins();
  cylinder(r=(n+1)*pin_distance,h=base_height);
}

module rectangular_board(sx=1, sy=1) {
  translate([0,0,base_height-0.01]) {
    for(x=[1:1:sx]) for(y=[1:1:sy]) {
      translate([x*pin_distance,y*pin_distance,0]) pin();
    }
  }
  cube([(sx+1)*pin_distance,(sy+1)*pin_distance,base_height]);
}

module heart_board(n=3) {
  module half_circle_board(n) {
    intersection() {
      circle_board(n);
      inf=10000;
      translate([0,inf/2-pin_distance/2,0]) cube([inf,inf,inf],center=true);
    }
  }
  w = n*2 + 1;
  rectangular_board(w,w);
  translate([w*pin_distance,0,0]) rectangular_board(n-1,w);
  translate([0,w*pin_distance,0]) rectangular_board(w,n-1);
  translate([(n+1)*pin_distance,(w+n)*pin_distance,0]) half_circle_board(n);
  translate([(w+n)*pin_distance,(n+1)*pin_distance,0]) rotate([0,0,-90])half_circle_board(n);
}

function triangle_h(a) = a*sqrt(3)/2;

module triangle_board(n=3) {
  translate([0,0,base_height-0.01]) {
    for(x=[0:1:n-1]) for(y=[n - x-1:-1:0]) {
      translate([pin_distance*triangle_h(x-(n-1)/3), pin_distance*(y+x/2-(n-1)/2),0]) pin();
    }
  }
  minkowski() {
    cylinder(d=pin_distance*((n-1)*2*sqrt(3)/3),h=base_height-0.5,$fn=3);
    cylinder(r=pin_distance,h=0.5);
  }
}

module hexagon_board(n=3) {
  for(a=[0:60:359]) {
    rotate([0,0,a]) {
      translate([-pin_distance*triangle_h(n-1)*2/3,0,0])
        triangle_board(n);
    }
  }
}

module star_board(n=3) {
  for(a=[0:60:359]) {
    rotate([0,0,a]) {
      translate([-pin_distance*triangle_h(n-1)*2/3,0,0])
        triangle_board(n);
      translate([-pin_distance*triangle_h(n-1)*4/3,0,0])
        mirror([1,0,0])
        triangle_board(n);
    }
  }
}

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