Rework the buildbox shape, making it more consistent. It now offers an option to center the shape, and it does not apply the render mode anymore.

/**
 * @license
 * MIT License
 *
 * Copyright (c) 2017-2020 Jean-Sebastien CONAN
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * Part of the camelSCAD library.
 *
 * Build box visualization.
 *
 * @package shape/context
 * @author jsconan
 */

/**
 * Computes the size of the build plate.
 *
 * @param Number|Vector [size] - The size of the build plate.
 * @param Number|Vector [cell] - The size of each cell on the build plate.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of a cell.
 * @param Number [cw] - The width of cell.
 * @returns Vector - Returns the size vector.
 */
function sizeBuildPlate(size, cell, l, w, cl, cw) =
    let(
        size = apply2D(uor(size, DEFAULT_BUILD_PLATE_SIZE), l, w),
        cell = apply2D(uor(cell, DEFAULT_BUILD_PLATE_CELL), cl, cw),
        nb = [
            cell[0] ? floor(size[0] / cell[0]) : 0,
            cell[1] ? floor(size[1] / cell[1]) : 0
        ],
        count = [
            nb[0] + 1,
            nb[1] + 1
        ],
        offset = [
            cell[0] ? -nb[0] * cell[0] / 2 : 0,
            cell[1] ? -nb[1] * cell[1] / 2 : 0
        ]
    )
    [ size, cell, count, offset ]
;

/**
 * Creates a build plate visualization at the origin.
 *
 * @param Number|Vector [size] - The size of the build plate.
 * @param Number|Vector [cell] - The size of each cell on the build plate.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of a cell.
 * @param Number [cw] - The width of cell.
 * @param Boolean [center] - The shape is centered vertically.
 */
module buildPlate(size=DEFAULT_BUILD_PLATE_SIZE, cell=DEFAULT_BUILD_PLATE_CELL, l, w, cl, cw, center=false) {
    size = sizeBuildPlate(size=size, cell=cell, l=l, w=w, cl=cl, cw=cw);
    plateSize = size[0];
    cellSize = size[1];
    cellCount = size[2];
    cellOffset = size[3];

    plateHeight = 1;
    lineWidth = .5;

    %color([1, 1, 1, .2]) {
        negativeExtrude(height=-plateHeight, direction=0) {
            translate(center ? -plateSize / 2 : [0, 0]) {
                square(plateSize);
            }
        }
        negativeExtrude(height=-plateHeight, direction=2) {
            translate(center ? [cellOffset[0], -plateSize[1] / 2, 0] : [0, 0, 0]) {
                repeat(count=cellCount[0], intervalX=cellSize[0]) {
                    square([lineWidth, plateSize[1]]);
                }
            }
            translate(center ? [-plateSize[0] / 2, cellOffset[1], 0] : [0, 0, 0]) {
                repeat(count=cellCount[1], intervalY=cellSize[1]) {
                    square([plateSize[0], lineWidth]);
                }
            }
        }
    }
}

/**
 * Creates a build volume visualization at the origin.
 *
 * @param Number|Vector [size] - The size of the build box.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Boolean [center] - The shape is centered vertically.
 */
module buildVolume(size=DEFAULT_BUILD_VOLUME_SIZE, l, w, h, center=false) {
    %color([1, 1, 1, .1]) {
        size = apply3D(size, l, w, w);
        translate(center ? apply3D(-size / 2, z=0) : [0, 0, 0]) {
            cube(size);
        }
    }
}

/**
 * Creates a build box visualization at the origin.
 * A build box contains visualizations for a build plate and a build volume.
 *
 * @param Number|Vector [size] - The size of the build volume.
 * @param Number|Vector [cell] - The size of each cell on the build plate.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [cl] - The length of a cell.
 * @param Number [cw] - The width of cell.
 * @param Boolean [center] - The shape is centered vertically.
 */
module buildBox(size=DEFAULT_BUILD_VOLUME_SIZE, cell=DEFAULT_BUILD_PLATE_CELL, l, w, h, cl, cw, center=false) {
    buildPlate(size=size, cell=cell, l=l, w=w, cl=cl, cw=cw, center=center);
    buildVolume(size=size, l=l, w=w, h=h, center=center);

    children();
}

/**
 * @license
 * MIT License
 *
 * Copyright (c) 2017 Jean-Sebastien CONAN
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * Part of the camelSCAD library.
 *
 * Build box visualization.
 *
 * @package shape/context
 * @author jsconan
 */

/**
 * Computes the size of the build plate.
 *
 * @param Number|Vector [size] - The size of the build plate.
 * @param Number|Vector [cell] - The size of each cell on the build plate.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of a cell.
 * @param Number [cw] - The width of cell.
 * @returns Vector - Returns the size vector.
 */
function sizeBuildPlate(size, cell, l, w, cl, cw) =
    let(
        size = apply2D(uor(size, DEFAULT_BUILD_PLATE_SIZE), l, w),
        cell = apply2D(uor(cell, DEFAULT_BUILD_PLATE_CELL), cl, cw),
        nb = [
            cell[0] ? floor(size[0] / cell[0]) : 0,
            cell[1] ? floor(size[1] / cell[1]) : 0
        ],
        count = [
            nb[0] + 1,
            nb[1] + 1
        ],
        offset = [
            cell[0] ? -nb[0] * cell[0] / 2 : 0,
            cell[1] ? -nb[1] * cell[1] / 2 : 0
        ]
    )
    [ size, cell, count, offset ]
;

/**
 * Creates a build plate visualization at the origin.
 *
 * @param Number|Vector [size] - The size of the build plate.
 * @param Number|Vector [cell] - The size of each cell on the build plate.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of a cell.
 * @param Number [cw] - The width of cell.
 */
module buildPlate(size=DEFAULT_BUILD_PLATE_SIZE, cell=DEFAULT_BUILD_PLATE_CELL, l, w, cl, cw) {
    size = sizeBuildPlate(size=size, cell=cell, l=l, w=w, cl=cl, cw=cw);
    plateSize = size[0];
    cellSize = size[1];
    cellCount = size[2];
    cellOffset = size[3];

    plateHeight = 1;
    lineWidth = .5;

    %color([1, 1, 1, .2]) {
        negativeExtrude(height=-plateHeight, direction=0) {
            rectangle(plateSize);
        }
        negativeExtrude(height=-plateHeight, direction=2) {
            translateX(cellOffset[0]) {
                repeat(count=cellCount[0], intervalX=cellSize[0]) {
                    rectangle([lineWidth, plateSize[1]]);
                }
            }
            translateY(cellOffset[1]) {
                repeat(count=cellCount[1], intervalY=cellSize[1]) {
                    rectangle([plateSize[0], lineWidth]);
                }
            }
        }
    }
}

/**
 * Creates a build volume visualization at the origin.
 *
 * @param Number|Vector [size] - The size of the build box.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 */
module buildVolume(size=DEFAULT_BUILD_VOLUME_SIZE, l, w, h) {
    %color([1, 1, 1, .1]) {
        box(size=size, l=l, w=w, h=w);
    }
}

/**
 * Creates a build box visualization at the origin.
 * A build box contains visualizations for a build plate and a build volume.
 * It also applies a render mode.
 * @param Number|Vector [size] - The size of the build volume.
 * @param Number|Vector [cell] - The size of each cell on the build plate.
 * @param String [mode] - The mode to apply on the children modules.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [cl] - The length of a cell.
 * @param Number [cw] - The width of cell.
 */
module buildBox(size, cell, mode, l, w, h, cl, cw) {
    size = apply3D(uor(size, DEFAULT_BUILD_PLATE_SIZE), l, w, h);

    buildPlate(size=size, cell=cell, l=l, w=w, cl=cl, cw=cw);
    buildVolume(size=size, l=l, w=w, h=h);

    applyMode(mode) {
        children();
    }
}


attach: fix vector shape

attach: fix vector shape

include <system.scad>
use <misc.scad>
use <transforms.scad>;
use <shapes.scad>

// From Obiscad
//----------------------------------------------------------
//--  Draw a point in the position given by the vector p
//----------------------------------------------------------
module point(p, r=0.7, fn)
{
    translate(p)
    sphere(r=r);
}

//------------------------------------------------------------------
//-- Draw a vector poiting to the z axis
//-- This is an auxiliary module for implementing the vector module
//--
//-- Parameters:
//--  l: total vector length (line + arrow)
//--  l_arrow: Vector arrow length
//--  mark: If true, a mark is draw in the vector head, for having
//--    a visual reference of the rolling angle
//------------------------------------------------------------------
module vectorz(l=10, l_arrow=4, mark=true)
{
  //-- vector body length (not including the arrow)
  lb = l - l_arrow;

  //-- The vector is locatead at 0,0,0
  translate([0,0,lb/2])
  union() {

    //-- Draw the arrow
    translate([0,0,lb/2])
      cylindera(r1=2/2, r2=0.2, h=l_arrow);

    //-- Draw the mark
    if (mark) {
      translate([0,0,lb/2+l_arrow/2])
      translate(X)
        cubea([2,0.3,l_arrow*0.8]);
    }

    //-- Draw the body
    cylindera(r=1/2, h=lb, align=-Z);
  }

  //-- Draw a sphere in the vector base
  spherea(r=1/2, align=-Z);
}

// From Obiscad,
//---------------------------------------------------------------------------
//-- Draw a vector
//--
//-- There are two modes of drawing the vector
//-- * Mode 1: Given by a cartesian point(x,y,z). A vector from the origin
//--           to the end (x,y,z) is drawn. The l parameter (length) must
//--           be 0  (l=0)
//-- * Mode 2: Give by direction and length
//--           A vector of length l pointing to the direction given by
//--           v is drawn
//---------------------------------------------------------------------------
//-- Parameters:
//--  v: Vector cartesian coordinates
//--  l: total vector length (line + arrow)
//--  l_arrow: Vector arrow length
//    mark: If true, a mark is draw in the vector head, for having
//--    a visual reference of the rolling angle
//---------------------------------------------------------------------------

module vector(v, l=4, l_arrow=2, mark=false)
{
  //-- Get the vector length from the coordinates
  mod = v_mod(v);

  //-- The vector is very easy implemented by means of the orientate
  //-- operator:
  //--  orientate(v) vectorz(l=mod, l_arrow=l_arrow)
  //--  BUT... in OPENSCAD 2012.02.22 the recursion does not
  //--    not work, so that if the user use the orientate operator
  //--    on a vector, openscad will ignore it..
  //-- The solution at the moment (I hope the openscad developers
  //--  implement the recursion in the near future...)
  //--  is to repite the orientate operation in this module

  //---- SAME CALCULATIONS THAN THE ORIENTATE OPERATOR!
  //-- Calculate the rotation axis

  vref = Z;
  raxis = v_cross(vref,v);

  //-- Calculate the angle between the vectors
  ang = v_anglev(vref,v);

  raxis_=ang==180&&raxis==N?X:raxis;

  //-- orientate the vector
  //-- Draw the vector. The vector length is given either
  //--- by the mod variable (when l=0) or by l (when l!=0)
  if (l==0)
    rotate(a=ang, v=raxis_)
      vectorz(l=mod, l_arrow=l_arrow, mark=mark);
  else
    rotate(a=ang, v=raxis_)
      vectorz(l=l, l_arrow=l_arrow, mark=mark);

}

// From Obiscad,
//--------------------------------------------------------------------
//-- Draw a connector
//-- A connector is defined a 3-tuple that consist of a point
//--- (the attachment point), and axis (the attachment axis) and
//--- an angle the connected part should be rotate around the
//--  attachment axis
//--
//--- Input parameters:
//--
//--  Connector c = [p , n, ang] where:
//--
//--     p : The attachment point
//--     v : The attachment axis
//--   ang : the angle
//--------------------------------------------------------------------
module connector(c)
{
  //-- Get the three components from the connector
  p = c[0];
  v = c[1];
  ang = c[2];

  //-- Draw the attachment poing
  color("Gray") point(p);

  //-- Draw the attachment axis vector (with a mark)
  translate(p)
    rotate(a=ang, v=v)
    color("Gray") vector(v=v_unitv(v)*6, l_arrow=2, mark=true);
}

// From Obiscad,
// modified to take roll parameter as param in module instead of attachment points
//-------------------------------------------------------------------------
//--  ATTACH OPERATOR
//--  This operator applies the necesary transformations to the
//--  child (attachable part) so that it is attached to the main part
//--
//--  Parameters
//--    a -> Connector of the main part
//--    b -> Connector of the attachable part
//-------------------------------------------------------------------------
module attach(a, b, roll=0, rollaxis)
{
    //-- Get the data from the connectors
    pos1 = a[0];  //-- Attachment point. Main part
    v    = a[1];  //-- Attachment axis. Main part

    pos2 = b[0];  //-- Attachment point. Attachable part
    vref = b[1];  //-- Atachment axis. Attachable part

    //-------- Calculations for the "orientate operator"------
    //-- Calculate the rotation axis
    raxis = v_cross(vref,v);

    //-- Calculate the angle between the vectors
    ang = v_anglev(vref,v);
    //--------------------------------------------------------.-

    raxis_=ang==180&&raxis==N?X:raxis;

    //-- Apply the transformations to the child ---------------------------

    //-- Place the attachable part on the main part attachment point
    translate(pos1)
        //-- Orientate operator. Apply the orientation so that
        //-- both attachment axis are paralell. Also apply the roll angle
        rotate(a=roll, v=rollaxis==U?v:rollaxis)  rotate(a=ang, v=raxis_)
        //-- Attachable part to the origin
        translate(-pos2)
        children();
}

include <system.scad>
use <misc.scad>
use <transforms.scad>;
use <shapes.scad>

// From Obiscad
//----------------------------------------------------------
//--  Draw a point in the position given by the vector p
//----------------------------------------------------------
module point(p, r=0.7, fn)
{
    translate(p)
    sphere(r=r);
}

//------------------------------------------------------------------
//-- Draw a vector poiting to the z axis
//-- This is an auxiliary module for implementing the vector module
//--
//-- Parameters:
//--  l: total vector length (line + arrow)
//--  l_arrow: Vector arrow length
//--  mark: If true, a mark is draw in the vector head, for having
//--    a visual reference of the rolling angle
//------------------------------------------------------------------
module vectorz(l=10, l_arrow=4, mark=false)
{
  //-- vector body length (not including the arrow)
  lb = l - l_arrow;

  //-- The vector is locatead at 0,0,0
  translate([0,0,lb/2])
  union() {

    //-- Draw the arrow
    translate([0,0,lb/2])
      cylindera(r1=2/2, r2=0.2, h=l_arrow);

    //-- Draw the mark
    if (mark) {
      translate([0,0,lb/2+l_arrow/2])
      translate(X)
        cubea([2,0.3,l_arrow*0.8]);
    }

    //-- Draw the body
    cylindera(r=1/2, h=lb, center=true);
  }

  //-- Draw a sphere in the vector base
  sphere(r=1/2);
}

// From Obiscad,
//---------------------------------------------------------------------------
//-- Draw a vector
//--
//-- There are two modes of drawing the vector
//-- * Mode 1: Given by a cartesian point(x,y,z). A vector from the origin
//--           to the end (x,y,z) is drawn. The l parameter (length) must
//--           be 0  (l=0)
//-- * Mode 2: Give by direction and length
//--           A vector of length l pointing to the direction given by
//--           v is drawn
//---------------------------------------------------------------------------
//-- Parameters:
//--  v: Vector cartesian coordinates
//--  l: total vector length (line + arrow)
//--  l_arrow: Vector arrow length
//    mark: If true, a mark is draw in the vector head, for having
//--    a visual reference of the rolling angle
//---------------------------------------------------------------------------

module vector(v,l=0, l_arrow=4, mark=false)
{
  //-- Get the vector length from the coordinates
  mod = v_mod(v);

  //-- The vector is very easy implemented by means of the orientate
  //-- operator:
  //--  orientate(v) vectorz(l=mod, l_arrow=l_arrow)
  //--  BUT... in OPENSCAD 2012.02.22 the recursion does not
  //--    not work, so that if the user use the orientate operator
  //--    on a vector, openscad will ignore it..
  //-- The solution at the moment (I hope the openscad developers
  //--  implement the recursion in the near future...)
  //--  is to repite the orientate operation in this module

  //---- SAME CALCULATIONS THAN THE ORIENTATE OPERATOR!
  //-- Calculate the rotation axis

  vref = Z;
  raxis = v_cross(vref,v);

  //-- Calculate the angle between the vectors
  ang = v_anglev(vref,v);

  raxis_=ang==180&&raxis==N?X:raxis;

  //-- orientate the vector
  //-- Draw the vector. The vector length is given either
  //--- by the mod variable (when l=0) or by l (when l!=0)
  if (l==0)
    rotate(a=ang, v=raxis_)
      vectorz(l=mod, l_arrow=l_arrow, mark=mark);
  else
    rotate(a=ang, v=raxis_)
      vectorz(l=l, l_arrow=l_arrow, mark=mark);

}

// From Obiscad,
//--------------------------------------------------------------------
//-- Draw a connector
//-- A connector is defined a 3-tuple that consist of a point
//--- (the attachment point), and axis (the attachment axis) and
//--- an angle the connected part should be rotate around the
//--  attachment axis
//--
//--- Input parameters:
//--
//--  Connector c = [p , n, ang] where:
//--
//--     p : The attachment point
//--     v : The attachment axis
//--   ang : the angle
//--------------------------------------------------------------------
module connector(c)
{
  //-- Get the three components from the connector
  p = c[0];
  v = c[1];
  ang = c[2];

  //-- Draw the attachment poing
  color("Gray") point(p);

  //-- Draw the attachment axis vector (with a mark)
  translate(p)
    rotate(a=ang, v=v)
    color("Gray") vector(v=v_unitv(v)*6, l_arrow=2, mark=true);
}

// From Obiscad,
// modified to take roll parameter as param in module instead of attachment points
//-------------------------------------------------------------------------
//--  ATTACH OPERATOR
//--  This operator applies the necesary transformations to the
//--  child (attachable part) so that it is attached to the main part
//--
//--  Parameters
//--    a -> Connector of the main part
//--    b -> Connector of the attachable part
//-------------------------------------------------------------------------
module attach(a, b, roll=0, rollaxis)
{
    //-- Get the data from the connectors
    pos1 = a[0];  //-- Attachment point. Main part
    v    = a[1];  //-- Attachment axis. Main part

    pos2 = b[0];  //-- Attachment point. Attachable part
    vref = b[1];  //-- Atachment axis. Attachable part

    //-------- Calculations for the "orientate operator"------
    //-- Calculate the rotation axis
    raxis = v_cross(vref,v);

    //-- Calculate the angle between the vectors
    ang = v_anglev(vref,v);
    //--------------------------------------------------------.-

    raxis_=ang==180&&raxis==N?X:raxis;

    //-- Apply the transformations to the child ---------------------------

    //-- Place the attachable part on the main part attachment point
    translate(pos1)
        //-- Orientate operator. Apply the orientation so that
        //-- both attachment axis are paralell. Also apply the roll angle
        rotate(a=roll, v=rollaxis==U?v:rollaxis)  rotate(a=ang, v=raxis_)
        //-- Attachable part to the origin
        translate(-pos2)
        children();
}


xaxis/carriage: render extruder motor heatsink+fan


Create a support for component to be integrated in waterproof pocket

thickness = 2;
width=85;
length=133-30;
nano_length_max=43.6;
nano_length_min = 37.1;
nano_width_max = 22.7;
nano_internal_width = 9;
nano_thickness=7;
9V_width=26.2;
9V_length=45;
transmitter_width = 30;
transmitter_length= 45;
IMU_screw_spacing_width = 12.1;
IMU_screw_spacing_length = 16.3;
corner_radius=5;

module support()
{
	difference()
	{
		minkowski(){
		translate([0,-15,0]) cube(size=[width-2*corner_radius,length-2*corner_radius,thickness/3.], center=true);
		cylinder(h=thickness/3., r=corner_radius);
}
		translate([10,12,0]) difference(){
			cube(size=[nano_width_max,nano_length_min,2*thickness], center=true);
		 	cube(size=[nano_internal_width,nano_length_min,2*thickness], center=true);
	}
		translate([-23,8,0]) cube(size=[9V_width,9V_length,2*thickness], center=true);
		//translate([10,-45,0]) cube(size=[transmitter_length,transmitter_width,2*thickness], center=true);
	translate([0,-60,0]) cube(size=[12,3,2*thickness], center=true);
	translate([0,-60 +transmitter_width ,0]) cube(size=[12,3,2*thickness], center=true);

	// Holes to screw drotek IMU board
		translate([-30, -50,0]) cylinder(r=0.3, h=2*thickness, center=true);
		translate([-30+IMU_screw_spacing_length, -50+IMU_screw_spacing_width,0]) cylinder(r=0.3, h=2*thickness, center=true);
		translate([-30+IMU_screw_spacing_length, -50,0]) cylinder(r=0.3, h=2*thickness, center=true);
	}
}
projection() support();

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


fixup! main/zaxis: Improve leadscrew/rod distance calc

include <bearings.scad>
include <screws.scad>
include <thing_libutils/metric-thread.scad>

e=0.01;

// resolution of any round object (segment length)
fnr                         = 0.4;

extrusion_height            = 0.4*mm;

// width of a single wall, should match your slicer settings
extrusion_width             = 0.4*mm;

// how many lines should a normal wall have (i.e. 0.6(extrusion_width)*6(normal_wall_factor)= 3.6mm wall width)
normal_wall_factor          = 3;

thick_wall_factor           = 4;

// diameter of your filament.
filament_d                  = 1.75*mm;
filament_r                  = filament_d/2;

main_width = 340*mm;
main_depth = 420*mm;
main_height = 400*mm;
main_upper_width = 420*mm;

extrusion_color = [0.5,0.5,0.5];
extrusion_size = 20*mm;
extrusion_thread = ThreadM5;

main_lower_dist_z= 80*mm;
main_upper_dist_y= 160*mm;

xaxis_rod_distance = 45*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_bearing=bearing_igus_rj4jp_01_10;

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing=bearing_igus_rj4jp_01_12;
ycarriage_size=[220*mm,220*mm,5*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
zaxis_bearing=bearing_igus_rj4jp_01_12;

// NEMA17 motor w/340mm leadscrew
zaxis_motor = [
                [NemaModel, 17],
                [NemaLengthShort, 33*mm],
                [NemaLengthMedium, 39*mm],
                [NemaLengthLong, 47*mm],
                [NemaSideSize, 42.20*mm],
                [NemaDistanceBetweenMountingHoles, 31.04*mm],
                [NemaMountingHoleDiameter, 4*mm],
                [NemaMountingHoleDepth, 4.5*mm],
                [NemaMountingHoleLip, -1*mm],
                [NemaMountingHoleCutoutRadius, 0*mm],
                [NemaEdgeRoundingRadius, 7*mm],
                [NemaRoundExtrusionDiameter, 22*mm],
                [NemaRoundExtrusionHeight, 1.9*mm],
                [NemaAxleDiameter, 8*mm],
                // custom front axle length
                [NemaFrontAxleLength, 340*mm],
                [NemaBackAxleLength, 15*mm],
                [NemaAxleFlatDepth, 0.5*mm],
                [NemaAxleFlatLengthFront, 15*mm],
                [NemaAxleFlatLengthBack, 14*mm]
         ];

zaxis_motor_offset_z = 10*mm;

// inner_d, outer_d, thread
zaxis_nut = [20*mm, 36.5*mm, 8*mm];

zaxis_nut_mount_outer = zaxis_nut[1]/2 + zaxis_bearing[1]/2 + 3;

// place z rod on edge of motor
/*zaxis_rod_screw_distance_x = max(zaxis_nut_mount_outer, zaxis_rod_d/2 + lookup(NemaSideSize,zaxis_motor)/2);*/
zaxis_rod_screw_distance_x = zaxis_nut_mount_outer;

xaxis_zaxis_distance_y = xaxis_rod_d/2 + zaxis_bearing[1]/2;

include <bearings.scad>
include <screws.scad>
include <thing_libutils/metric-thread.scad>

e=0.01;

// resolution of any round object (segment length)
fnr                         = 0.4;

extrusion_height            = 0.4*mm;

// width of a single wall, should match your slicer settings
extrusion_width             = 0.4*mm;

// how many lines should a normal wall have (i.e. 0.6(extrusion_width)*6(normal_wall_factor)= 3.6mm wall width)
normal_wall_factor          = 3;

thick_wall_factor           = 4;

// diameter of your filament.
filament_d                  = 1.75*mm;
filament_r                  = filament_d/2;

main_width = 340*mm;
main_depth = 420*mm;
main_height = 400*mm;
main_upper_width = 420*mm;

extrusion_color = [0.5,0.5,0.5];
extrusion_size = 20*mm;
extrusion_thread = ThreadM5;

main_lower_dist_z= 80*mm;
main_upper_dist_y= 160*mm;

xaxis_rod_distance = 45*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_bearing=bearing_igus_rj4jp_01_10;

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing=bearing_igus_rj4jp_01_12;
ycarriage_size=[220*mm,220*mm,5*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
zaxis_bearing=bearing_igus_rj4jp_01_12;

// NEMA17 motor w/340mm leadscrew
zaxis_motor = [
                [NemaModel, 17],
                [NemaLengthShort, 33*mm],
                [NemaLengthMedium, 39*mm],
                [NemaLengthLong, 47*mm],
                [NemaSideSize, 42.20*mm],
                [NemaDistanceBetweenMountingHoles, 31.04*mm],
                [NemaMountingHoleDiameter, 4*mm],
                [NemaMountingHoleDepth, 4.5*mm],
                [NemaMountingHoleLip, -1*mm],
                [NemaMountingHoleCutoutRadius, 0*mm],
                [NemaEdgeRoundingRadius, 7*mm],
                [NemaRoundExtrusionDiameter, 22*mm],
                [NemaRoundExtrusionHeight, 1.9*mm],
                [NemaAxleDiameter, 8*mm],
                // custom front axle length
                [NemaFrontAxleLength, 340*mm],
                [NemaBackAxleLength, 15*mm],
                [NemaAxleFlatDepth, 0.5*mm],
                [NemaAxleFlatLengthFront, 15*mm],
                [NemaAxleFlatLengthBack, 14*mm]
         ];

zaxis_motor_offset_z = 10*mm;

// place z rod on edge of motor
zaxis_rod_screw_distance_x = lookup(NemaSideSize,zaxis_motor);

xaxis_zaxis_distance_y = xaxis_rod_d/2 + zaxis_bearing[1]/2;


Tri at my age ...

Tri at my age ...

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

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

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

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

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

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

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

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

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

module 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 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);
    }
}

shedBase(shed_length, shed_width, number_x=5,number_y=1, braces=1);
translate([0,0,base_timber]) floorMembrane(shed_length, shed_width, thickness = 1);
translate([0,0,base_timber+1]) shedLowerFloor(shed_length, shed_width);
translate([0,shed_width-base_timber,base_timber+1+base_sheet_t])  backWallStruts(shed_length, shed_front_back, 5);
translate([base_timber,base_timber,base_timber+1+base_sheet_t])  sideWallStruts(shed_width-base_timber*2,shed_front_back,2, braces=1);
translate([shed_length,base_timber,base_timber+1+base_sheet_t])  sideWallStruts(shed_width-base_timber*2,shed_front_back,2, braces=1);

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);

roof(shed_length, shed_width,shed_front_height,shed_front_back);

//shedBaseSection(shed_length/6,shed_width, braces = 1);

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

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

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

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

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

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

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

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

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

module 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 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;
    // 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);
    translate([0,0,z_front+base_timber+panel_slf_t+height_adjust])
    {
        rotate([-theta,0,0]) cubeI([panel_slf_w,panel_slf_l, panel_slf_t]);
    }
}

shedBase(shed_length, shed_width, number_x=5,number_y=1, braces=1);
translate([0,0,base_timber]) floorMembrane(shed_length, shed_width, thickness = 1);
translate([0,0,base_timber+1]) shedLowerFloor(shed_length, shed_width);
translate([0,shed_width-base_timber,base_timber+1+base_sheet_t])  backWallStruts(shed_length, shed_front_back, 5);
translate([base_timber,base_timber,base_timber+1+base_sheet_t])  sideWallStruts(shed_width-base_timber*2,shed_front_back,2, braces=1);
translate([shed_length,base_timber,base_timber+1+base_sheet_t])  sideWallStruts(shed_width-base_timber*2,shed_front_back,2, braces=1);

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);

roof(shed_length, shed_width,shed_front_height,shed_front_back);

//shedBaseSection(shed_length/6,shed_width, braces = 1);


tried to make H node a bit thinner. Also trying to bring legs in a little closer to main bar to save width

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/Jansen.scad $
// $Id: Jansen.scad 427 2014-08-23 20:42:39Z mrwhat $

// Define PART to one of the following values to generate model for desired part.
//       HipA, HipB, FootA, FootB, CH, CD, EF, BH, AC, pulley, mainBar, drivePulley
// For a 2-leg (half-trotter) :  print (2) CH, CD ; (4) EF, BH ; (1) of the others
// For a production robot, glue a rectangular support/spacer between BH pairs for stiffness

// *** DEPRICATED
// Combined parts with pads, optimized for RepRap :
// Hip, Feet, crankLinks, EFs, BHs    : main, pulley, drivePulley as above (brace)
//
// standoffs also DEPRICATED
hingeStyle = "spacer"; //6standoff";  // spacer or standoff
// *****

PART="pulley";
echo(str("PART=",PART));

HoleFuzz = 0.1;  // extra radius (mm) to add to holes to account for printer slop
dHoleFuzz = 0.2;  // extra radius (mm) to add to d-shaft holes.  Sometimes not the same as HoleFuzz since it is harder to clean D-shaft holes

// measured diameter of '3/16"' spacer was 4.74 to 4.76, not 4.7625 as expected.
// Current design:  3/16" axles at B
//                  3/16" long 1/4"  OD standoffs at D, E, F
//                  1/2"  long 3/16" OD standoffs at H, A, C
Bdiam = 4.7625;  // larger brass tube rdiameter, measured on 3/16" tube
Adiam = 4.76;
Hdiam = Adiam;
//Ddiam = 6.35;  // 1/4" OD standoffs
Ddiam = Adiam;  // 3/16" OD standoffs/spacers
diam4 = 2.76;  // diameter of #4-40 screw, OD of thread

// on spacer tests:
//    Brad +.125 mm was snug, but not quite free rotating
//         +.05     turned, but not freely
//         -.025    still turned,  was very close
//    Arad +.125    turned free (good for main, crankLinks)
//         +.05     was press-to-fit (good for crankArm)
//    rad4 + 0.2    allowed a screw to go through snugly but freely
//         +.125    only threaded through
//  1/4"OD + 0.2    was a snug fit, no turn.  almost press-to-fit
//         + 0.275  snug, free turn... good for hinges on standoff

Brad = Bdiam/2 + HoleFuzz/2;    // 4.76mm diam brass tube -- critical fit
Arad = Adiam/2 + HoleFuzz/2.3;  // 3.18mm diam brass tube -- critical fit
rad4 = diam4/2 + HoleFuzz;  // good for screw pass-through
Hrad = Hdiam/2 + HoleFuzz*1.35;  // standoff holes for freely-moving hinges
Drad = Ddiam/2 + HoleFuzz;
AradFree = Adiam/2 + .25;  // loose fit on spindle

BradTight = Brad-0.05;
BradFree  = Brad+0.05;

Frad = 7;  // radius of beefed-up "knee"

LinkRad=3;
BarHeight=3;
//NodeHeight=5.8;  // gives a little room for 6.35 mm (.25 inch) standoffs
layer1bias=0.4;  // shift up for 1 layer of brim/raft

// 9/16" spacer height 14.37mm, not 14.287 as expected
// 3/16" spacer height  4.79mm, not 4.7625 as expected (*3=14.37)
// 1/4" Al standoffs were pretty close, and 3x was 19.02mm high, not 19.05 as expected, pretty close
//TrueNodeHeight = (hingeStyle == "spacer") ? 4.79-.2 : 6.35;
TrueNodeHeight = 4.79-.2;
NodeHeight = TrueNodeHeight - 0.3;  // a little room for hinges
//NodeHeight3 = 25.4*((hingeStyle == "spacer") ? 9/16 : 3/4) - 0.3;
// moving to slightly thinner 1/2" standoffs at H
NodeHeight3 = 25.4/2 - 0.3;

// Forks should be 1 node thick for standoffs...  short screws go into variable length standoff.
// they should be 2 nodes thick for spacers, extra long so that ALL hinges are 5 nodes wide.
//ForkHeight = (hingeStyle == "spacer") ? 2*NodeHeight : NodeHeight;
ForkHeight = NodeHeight;

// definitions of linkage lengths: AC;Ay;Bx;BH;EF;CD;CH;BD;BE;DE;FG;FH;GH
// derived quantities: DEleft;FGleft;DEperp;FGperp
include <JansenDefs.scad>;

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//       define some standard part dimensions for re-use in groups, etc.
acH0 = NodeHeight;
acH1 = acH0+2;
acOR = Arad+3;
acIR = rad4;
pulleyR = 17;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

module nodeCyl(nodeHeight,nodeRad)
{ cylinder(h=nodeHeight,r1=nodeRad+.3,r2=nodeRad-.3,$fn=64); }  // set to 20+ for production quality

module drillHole(holeRad) { translate([0,0,-.03])
   cylinder(h=22,r=holeRad,$fn=80); } // set to 80 for production run

module footpad(r) { // pad to help a part stick to plate for 3D printer
   color("Cyan") cylinder(h=layer1bias,r1=r,r2=r-.3,$fn=11); }

// place a point, usually inside a linkage bar, to use in a hull
// with a part connected to a linkage bar
module barAnchor(dx) {
   translate([dx,0,0]) cylinder(h=BarHeight,r1=.8,r2=.6,$fn=6);
}

use <pulley.scad>;

include <JansenMain.scad>
include <JansenFoot.scad>

module monoBracedLinkage(len) {
lro = Drad+1.8;  // outisde link radius
difference() { union() { //------------------------ EF
    difference() { hull() {  // main bar
      translate([ 0 ,0,0])   nodeCyl(BarHeight,Frad);
      translate([len,0,0])   nodeCyl(BarHeight,lro*.5);
      }
      hull() { translate([0,0,-1.5]) { nodeCyl(BarHeight,Frad-1.5);
               translate([len,0 ,0])   nodeCyl(BarHeight,1); }}
    }

    // non-braced (BED side) reinforcement
    translate(  [len,0,0]) { nodeCyl(BarHeight,lro);
       hull() { translate([0,0,BarHeight-1])
          cylinder(h=ForkHeight-BarHeight+1,r1=lro-.8,r2=rad4+1.2,$fn=64);
          cylinder(h=NodeHeight-1,r1=lro+.1,r2=rad4+1.2,$fn=16);
          //barAnchor(-1.5*lro);
          translate([-2*lro,0,2]) sphere(r=.4,$fn=12);
       }
    }
    hull() { translate([1.3*Frad,0,1.5]) scale([1,1,1]) sphere(r=1,$fn=16);
        translate([0,0,BarHeight-1])
          cylinder(h=ForkHeight-BarHeight+1,r1=Frad-.6,r2=rad4+1.6,$fn=64); }
    cylinder(h=BarHeight-1,r1=rad4+2.2,r2=rad4+3.3,$fn=32);

    hull() { // out-of-plane ridge/brace
        translate([ 0 ,0,2.2]) scale([1,1,2]) sphere(r=1,$fn=16);
        translate([len,0,2.2]) scale([1,1,2]) sphere(r=1,$fn=16); }
    }
    drillHole(rad4);
    translate([len,0,0]) drillHole(rad4);
}}

//------------------------------------------------------------ crankLink
// linkage with thin, wide connection for crank side, full node height on other
module crankLink(len,dFlat,rHole) {
// changing crank spindle to a 3/16 spacer instead of the 1/8" brass tube
radA = AradFree;  // free spinning on 3/16 OD standoff
echo(str("rHole=",rHole));
difference() { union() {
   hull() { cylinder(h=NodeHeight/2,r1=radA+3,r2=radA+2.8,$fn=48);
      translate([dFlat+4,0,0]) cylinder(h=NodeHeight/2,r1=1.2,r2=1,$fn=6); }
   translate([len,0,0]) { hull() {
      cylinder(h=NodeHeight,r1=rHole+2.2,r2=rHole+2,$fn=48);
         translate([-rHole-4,0,0]) cylinder(h=BarHeight,r1=1.2,r2=1,$fn=6); }}
   hull() {                  cylinder(h=NodeHeight/2,r1=LinkRad+.4,r2=LinkRad,$fn=6);
      translate([len/2,0,0]) cylinder(h=NodeHeight/2,r1=LinkRad+.4,r2=LinkRad,$fn=6); }
   hull() { translate([dFlat-2,0,0]) cylinder(h=BarHeight,r1=LinkRad+.4,r2=LinkRad-.2,$fn=6);
            translate([len-2  ,0,0]) cylinder(h=BarHeight,r1=LinkRad+.4,r2=LinkRad-.2,$fn=6); }
   hull() {
      translate([dFlat+2  ,0,BarHeight-1]) scale([1,1,1.5]) sphere(r=1,$fn=12);
      translate([len-rHole,0,BarHeight-1]) scale([1,1,1.5]) sphere(r=1,$fn=12);
      translate([len*0.65 ,0,BarHeight+.5]){scale([0.6,0.6,1.7]) sphere(r=1,$fn=12);
         translate([0,0,-2]) scale([2,2,1]) sphere(r=1,$fn=12);}
      translate([dFlat+15 ,0,BarHeight+.5]){scale([0.6,0.6,1.7]) sphere(r=1,$fn=12);
         translate([0,0,-2]) scale([2,2,1]) sphere(r=1,$fn=12);}
      }
   }
   drillHole(radA);  // a little extra to move freely
   translate([len,0,0]) drillHole(rHole);
}}

module linkage1(len,h0,r0,d0,h1,r1,d1) { difference() { union() {
   hull() { barAnchor(1.5*r0);
      cylinder(h=h0,r1=r0+.2,r2=r0-0.2,$fn=48); }
   translate([len,0,0]) { hull() { barAnchor(-1.5*r1);
      cylinder(h=h1,r1=r1,r2=0.4*r1+0.6*d1,$fn=48); }}
   hull() {                cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6);
      translate([len,0,0]) cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6); }
   hull() {                   cylinder(h=h0-0.5,r1=2,r2=.6,$fn=6);
      translate([len-d1,0,0]) cylinder(h=h1-0.5,r1=2,r2=.6,$fn=6); }
   }
   drillHole(d0);
   translate([len,0,0]) drillHole(d1);
}}

module linkage(len,h0,r0,d0,h1,r1,d1) { difference() { union() {
echo(str("linkage:",len,",",h0,",",r0,",",d0,",",h1,",",r1,",",d1));
   hull() { barAnchor(2.5*r0);
      cylinder(h=h0,r1=r0+.1,r2=r0-0.2,$fn=48); }
   translate([len,0,0]) { hull() { barAnchor(-2.5*r1);
      cylinder(h=h1,r1=r1+.1,r2=r1-.2,$fn=48); }}
   hull() {                cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6);
      translate([len,0,0]) cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6); }
   hull() {                   cylinder(h=h0-0.5,r1=2,r2=.6,$fn=6);
      translate([len-d1,0,0]) cylinder(h=h1-0.5,r1=2,r2=.6,$fn=6); }
   }
   drillHole(d0);
   translate([len,0,0]) drillHole(d1);
}}

// beefier version of a simple linkage, with same ends on both sides
module brace(len,h0,r0) {
r1=r0+1.7;
difference() { union() {
   difference() { hull() { cylinder(h=3,r1=r1+.1,r2=r1-.1,$fn=48);
      translate([len,0,0]) cylinder(h=3,r1=r1+.1,r2=r1-.1,$fn=48); }
      translate([1.5,0,-1.5]) hull() { cylinder(h=3,r1=r1-1.6,r2=r1-1.4,$fn=6);
             translate([len-1.5,0,0])  cylinder(h=3,r1=r1-1.6,r2=r1-1.4,$fn=6); }}

   translate([len,0,0])
   hull() { cylinder(h=h0,r1=r1+.2,r2=r1-.1,$fn=48);
      translate([-r1-4,0,2]) sphere(r=1,$fn=12); }
   hull() { cylinder(h=h0,r1=r1+.2,r2=r1-.1,$fn=48);
      translate([ r1+4,0,2]) sphere(r=1,$fn=12); }

   translate([0,0,h0/2]) hull() { scale([1,1,h0/2]) sphere(r=1,$fn=12);
            translate([len,0,0])  scale([1,1,h0/2]) sphere(r=1,$fn=12); }

   }
   drillHole(r0);
   translate([len,0,0]) drillHole(r0);
}}

module crankArm(len,h0,r0,d0,h1,r1,d1) { difference() {
  linkage(len,h0,r0,d0,h1,r1,d1);

  //// add little hole for "cotter-wire" on crank arm
  //translate([0,0,h0/2]) rotate(a=[90,0,0])
  //   cylinder(h=3*r0,r=.8,$fn=80,center=true);

  // for change to using standoffs as axle, counter sink axle screw
  translate([0,0,h0-1.5]) cylinder(h=2+.2,r1=rad4,r2=3.3,$fn=24);

  // try another countersink for spindle screw.
  translate([len,0,-1]) cylinder(h=2.2,r1=3.3,r2=rad4,$fn=24);
}}

include <JansenBED.scad>;

//---------------------
module BED(dLeft,dBase,dPerp) { union() { rotate([0,0,50]) {
   translate([dBase*0.2,-3*Drad,0]) rotate([0,0,180]) mirror([1,0,0])
   BED_pad(dLeft,dBase,dPerp);
   BED_pad(dLeft,dBase,dPerp);
}}}
module feet(dLeft,dBase,dPerp) { union() {
   translate([dBase*0.15,-0.5*dPerp,0]) rotate([0,0,190]) mirror([1,0,0])
   bracedFoot_pad(dLeft,dBase,dPerp);
   bracedFoot_pad(dLeft,dBase,dPerp);
}}
module crankLinks() {
spc=6;
union() {
   translate([0,spc*3.2,0])
     crankLink_pad(CH,15,Hrad);
     crankLink_pad(CH,15,Hrad);
   rotate([0,0,180]) {
     translate([-CD-1.5*spc, spc*1.6,0]) crankLink_pad(CD,15,Drad);
     translate([-CD-1.5*spc,-spc*1.6,0]) crankLink_pad(CD,15,Drad); }

   // tight holes to glue to axle, not spin
   translate([5*spc,-3.2*spc,0])
     crankArm_pad(AC,acH0,acOR,acIR,acH1,acOR,acIR);
}}

module mainPulley() {
ph=5;  // pulley thickness
sr=25.4 * 3/16/2 + HoleFuzz;  // standoff countersink radius
sd=1; // standoff countersink distance

  // countersink main pulley for standoffs a bit.
  difference() {
    union() {
      pulley(18,ph,rad4,0);
      // pulley hub was 1.3 mm higher than outher thickness.  a little more for countersink
      cylinder(r1=5,r2=4,h=ph+1.5,$fn=36);  // give pulley a wider hub
    }

    translate([0,0,-1]) {
      cylinder(r=rad4,h=ph+3,$fn=17); // main threaded rod hole
      //cylinder(r=sr,h=1+sd+.2,$fn=28); // a little extra on bridged standoff depth
    }
    translate([0,0,ph+1.5-sd-.5]) cylinder(r=sr,h=3,$fn=28);
  }
}

//=====================================================
use <spacers.scad>;

if      (PART=="BED"  ) {                   BED(DEleft,DE,DEperp); }
//else if (PART=="BEDa" ) {                 imBED(DEleft,DE,DEperp); }
//else if (PART=="BEDb" ) { mirror([1,0,0]) imBED(DEleft,DE,DEperp); }
else if (PART=="HipA" ) {                 BED1(DEleft,DE,DEperp); }
else if (PART=="HipB" ) { mirror([1,0,0]) BED1(DEleft,DE,DEperp); }
else if (PART=="jHipA" ) { imBEDj(DEleft,DE,DEperp); }
else if (PART=="jHipB" ) { mirror([1,0,0]) imBEDj(DEleft,DE,DEperp); }
else if (PART=="Feet" )                         feet(FGleft,FG,FGperp);
else if (PART=="FootA")
//difference() {
                  bracedFoot(FGleft,FG,FGperp);
  //  translate([0,0,18]) cube([200,200,20],center=true); }
else if (PART=="FootB") { mirror([1,0,0]) bracedFoot(FGleft,FG,FGperp); }
else if (PART=="crankLinks") crankLinks();
else if (PART=="CH"   ) crankLink(CH,15,Hrad); // build 2
else if (PART=="CD"   ) crankLink(CD,15,Drad); // build 2
else if (PART=="EF"   ) monoBracedLinkage(EF); // build 4
else if (PART=="BH"   ) linkage1(BH,2.5*NodeHeight,Brad+2,BradFree,3,Hrad+2.5,rad4);
else if (PART=="AC"   ) crankArm(AC,acH0,acOR,acIR,acH1,acOR,acIR);
else if (PART=="halfPulley") { union() { color("Cyan") footpad(pulleyR+7);
       translate([0,0,.2]) halfPulley(pulleyR,2.5,AradTight,-1); }}
else if (PART=="halfDrivePulley") { union() { color("Cyan") footpad(15);
       translate([0,0,.1]) halfPulley(8,2.5,1.5+.3,1+.3); }}
else if (PART=="pulley") {  mainPulley(); }
else if (PART=="drivePulley") { pulley(10,4,1.5+dHoleFuzz,1+dHoleFuzz); }
else if (PART=="mainBar") {  mainBar(Bx,Ay); }
else if (PART=="braceBar") {  brace(2*Bx,8,Brad); }
else if (PART=="spacers") { union(){ spacers(NodeHeight/2,Bhole+3,Brad);
   translate([0,-7.5*LinkRad*1.414+1,0]) spacers(NodeHeight/2,LinkRad,rad4); }}
//else if (PART=="demo") { //show all unique parts
else {
   mainBar(Bx,Ay);
   #translate([0,Ay,20]) pulley(18,5,rad4,0);
   translate([0,-50,0])  pulley(10,4,1.5+.3,1+.3);
   translate([ 50, 30,0]) BED1(DEleft,DE,DEperp);//imBED(DEleft,DE,DEperp);
   translate([-26, 44,0]) rotate([0,0,180]) bracedFoot(FGleft,FG,FGperp);
   translate([-12,-16,0]) crankLink(CD,15,Drad);
   translate([-36,-28,0]) crankLink(CH,15,Hrad);
   translate([-73,-15,0]) monoBracedLinkage(EF);
   translate([-60, 15,0]) crankArm(AC,acH0,acOR,acIR,acH1,acOR,acIR);

   translate([ 25, 15,0]) linkage1(BH,2.5*NodeHeight,Brad+1.8,BradFree,ForkHeight,Hrad+2,rad4);
   translate([40,-42,0]) rotate([0,0,50]) brace(2*Bx,8,Brad);
}

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/Jansen.scad $
// $Id: Jansen.scad 427 2014-08-23 20:42:39Z mrwhat $

// Define PART to one of the following values to generate model for desired part.
//       HipA, HipB, FootA, FootB, CH, CD, EF, BH, AC, pulley, mainBar, drivePulley
// For a 2-leg (half-trotter) :  print (2) CH, CD ; (4) EF, BH ; (1) of the others
// For a production robot, glue a rectangular support/spacer between BH pairs for stiffness
//
// Combined parts with pads, optimized for RepRap :
// Hip, Feet, crankLinks, EFs, BHs    : main, pulley, drivePulley as above (brace)
PART="BH";
hingeStyle = "spacer"; //6standoff";  // spacer or standoff
echo(str("PART=",PART));

HoleFuzz = 0.1;  // extra radius (mm) to add to holes to account for printer slop
dHoleFuzz = 0.2;  // extra radius (mm) to add to d-shaft holes.  Sometimes not the same as HoleFuzz since it is harder to clean D-shaft holes

// measured diameter of '3/16"' spacer was 4.74 to 4.76, not 4.7625 as expected.
// Current design:  3/16" axles at B
//                  3/16" long 1/4"  OD standoffs at D, E, F
//                  1/2"  long 3/16" OD standoffs at H, A, C
Bdiam = 4.7625;  // larger brass tube rdiameter, measured on 3/16" tube
Adiam = 4.76;
Hdiam = Adiam;
//Ddiam = 6.35;  // 1/4" OD standoffs
Ddiam = Adiam;  // 3/16" OD standoffs/spacers
diam4 = 2.76;  // diameter of #4-40 screw, OD of thread

// on spacer tests:
//    Brad +.125 mm was snug, but not quite free rotating
//         +.05     turned, but not freely
//         -.025    still turned,  was very close
//    Arad +.125    turned free (good for main, crankLinks)
//         +.05     was press-to-fit (good for crankArm)
//    rad4 + 0.2    allowed a screw to go through snugly but freely
//         +.125    only threaded through
//  1/4"OD + 0.2    was a snug fit, no turn.  almost press-to-fit
//         + 0.275  snug, free turn... good for hinges on standoff

Brad = Bdiam/2 + HoleFuzz/2;    // 4.76mm diam brass tube -- critical fit
Arad = Adiam/2 + HoleFuzz/2.3;  // 3.18mm diam brass tube -- critical fit
rad4 = diam4/2 + HoleFuzz;  // good for screw pass-through
Hrad = Hdiam/2 + HoleFuzz*1.35;  // standoff holes for freely-moving hinges
Drad = Ddiam/2 + HoleFuzz;
AradFree = Adiam/2 + .25;  // loose fit on spindle

BradTight = Brad-0.05;
BradFree  = Brad+0.05;

Frad = 7;  // radius of beefed-up "knee"

LinkRad=3;
BarHeight=3;
//NodeHeight=5.8;  // gives a little room for 6.35 mm (.25 inch) standoffs
layer1bias=0.4;  // shift up for 1 layer of brim/raft

// 9/16" spacer height 14.37mm, not 14.287 as expected
// 3/16" spacer height  4.79mm, not 4.7625 as expected (*3=14.37)
// 1/4" Al standoffs were pretty close, and 3x was 19.02mm high, not 19.05 as expected, pretty close
//TrueNodeHeight = (hingeStyle == "spacer") ? 4.79-.2 : 6.35;
TrueNodeHeight = 4.79-.2;
NodeHeight = TrueNodeHeight - 0.3;  // a little room for hinges
//NodeHeight3 = 25.4*((hingeStyle == "spacer") ? 9/16 : 3/4) - 0.3;
// moving to slightly thinner 1/2" standoffs at H
NodeHeight3 = 25.4/2 - 0.3;

// Forks should be 1 node thick for standoffs...  short screws go into variable length standoff.
// they should be 2 nodes thick for spacers, extra long so that ALL hinges are 5 nodes wide.
//ForkHeight = (hingeStyle == "spacer") ? 2*NodeHeight : NodeHeight;
ForkHeight = NodeHeight;

// definitions of linkage lengths: AC;Ay;Bx;BH;EF;CD;CH;BD;BE;DE;FG;FH;GH
// derived quantities: DEleft;FGleft;DEperp;FGperp
include <JansenDefs.scad>;

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//       define some standard part dimensions for re-use in groups, etc.
acH0 = NodeHeight;
acH1 = acH0+2;
acOR = Arad+3;
acIR = rad4;
pulleyR = 17;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

module nodeCyl(nodeHeight,nodeRad)
{ cylinder(h=nodeHeight,r1=nodeRad+.3,r2=nodeRad-.3,$fn=64); }  // set to 20+ for production quality

module drillHole(holeRad) { translate([0,0,-.03])
   cylinder(h=22,r=holeRad,$fn=80); } // set to 80 for production run

module footpad(r) { // pad to help a part stick to plate for 3D printer
   color("Cyan") cylinder(h=layer1bias,r1=r,r2=r-.3,$fn=11); }

// place a point, usually inside a linkage bar, to use in a hull
// with a part connected to a linkage bar
module barAnchor(dx) {
   translate([dx,0,0]) cylinder(h=BarHeight,r1=.8,r2=.6,$fn=6);
}

use <pulley.scad>;

include <JansenMain.scad>
include <JansenFoot.scad>

module monoBracedLinkage(len) {
lro = Drad+1.8;  // outisde link radius
difference() { union() { //------------------------ EF
    difference() { hull() {  // main bar
      translate([ 0 ,0,0])   nodeCyl(BarHeight,Frad);
      translate([len,0,0])   nodeCyl(BarHeight,lro*.5);
      }
      hull() { translate([0,0,-1.5]) { nodeCyl(BarHeight,Frad-1.5);
               translate([len,0 ,0])   nodeCyl(BarHeight,1); }}
    }

    // non-braced (BED side) reinforcement
    translate(  [len,0,0]) { nodeCyl(BarHeight,lro);
       hull() { translate([0,0,BarHeight-1])
          cylinder(h=ForkHeight-BarHeight+1,r1=lro-.8,r2=rad4+1.2,$fn=64);
          cylinder(h=NodeHeight-1,r1=lro+.1,r2=rad4+1.2,$fn=16);
          //barAnchor(-1.5*lro);
          translate([-2*lro,0,2]) sphere(r=.4,$fn=12);
       }
    }
    hull() { translate([1.3*Frad,0,1.5]) scale([1,1,1]) sphere(r=1,$fn=16);
        translate([0,0,BarHeight-1])
          cylinder(h=ForkHeight-BarHeight+1,r1=Frad-.6,r2=rad4+1.6,$fn=64); }
    cylinder(h=BarHeight-1,r1=rad4+2.2,r2=rad4+3.3,$fn=32);

    hull() { // out-of-plane ridge/brace
        translate([ 0 ,0,2.2]) scale([1,1,2]) sphere(r=1,$fn=16);
        translate([len,0,2.2]) scale([1,1,2]) sphere(r=1,$fn=16); }
    }
    drillHole(rad4);
    translate([len,0,0]) drillHole(rad4);
}}

//------------------------------------------------------------ crankLink
// linkage with thin, wide connection for crank side, full node height on other
module crankLink(len,dFlat,rHole) {
// changing crank spindle to a 3/16 spacer instead of the 1/8" brass tube
radA = AradFree;  // free spinning on 3/16 OD standoff
echo(str("rHole=",rHole));
difference() { union() {
   hull() { cylinder(h=NodeHeight/2,r1=radA+3,r2=radA+2.8,$fn=48);
      translate([dFlat+4,0,0]) cylinder(h=NodeHeight/2,r1=1.2,r2=1,$fn=6); }
   translate([len,0,0]) { hull() {
      cylinder(h=NodeHeight,r1=rHole+2.2,r2=rHole+2,$fn=48);
         translate([-rHole-4,0,0]) cylinder(h=BarHeight,r1=1.2,r2=1,$fn=6); }}
   hull() {                  cylinder(h=NodeHeight/2,r1=LinkRad+.4,r2=LinkRad,$fn=6);
      translate([len/2,0,0]) cylinder(h=NodeHeight/2,r1=LinkRad+.4,r2=LinkRad,$fn=6); }
   hull() { translate([dFlat-2,0,0]) cylinder(h=BarHeight,r1=LinkRad+.4,r2=LinkRad-.2,$fn=6);
            translate([len-2  ,0,0]) cylinder(h=BarHeight,r1=LinkRad+.4,r2=LinkRad-.2,$fn=6); }
   hull() {
      translate([dFlat+2  ,0,BarHeight-1]) scale([1,1,1.5]) sphere(r=1,$fn=12);
      translate([len-rHole,0,BarHeight-1]) scale([1,1,1.5]) sphere(r=1,$fn=12);
      translate([len*0.65 ,0,BarHeight+.5]){scale([0.6,0.6,1.7]) sphere(r=1,$fn=12);
         translate([0,0,-2]) scale([2,2,1]) sphere(r=1,$fn=12);}
      translate([dFlat+15 ,0,BarHeight+.5]){scale([0.6,0.6,1.7]) sphere(r=1,$fn=12);
         translate([0,0,-2]) scale([2,2,1]) sphere(r=1,$fn=12);}
      }
   }
   drillHole(radA);  // a little extra to move freely
   translate([len,0,0]) drillHole(rHole);
}}

module linkage1(len,h0,r0,d0,h1,r1,d1) { difference() { union() {
   hull() { barAnchor(1.5*r0);
      cylinder(h=h0,r1=r0+.2,r2=r0-0.2,$fn=48); }
   translate([len,0,0]) { hull() { barAnchor(-1.5*r1);
      cylinder(h=h1,r1=r1,r2=0.4*r1+0.6*d1,$fn=48); }}
   hull() {                cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6);
      translate([len,0,0]) cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6); }
   hull() {                   cylinder(h=h0-0.5,r1=2,r2=.6,$fn=6);
      translate([len-d1,0,0]) cylinder(h=h1-0.5,r1=2,r2=.6,$fn=6); }
   }
   drillHole(d0);
   translate([len,0,0]) drillHole(d1);
}}

module linkage(len,h0,r0,d0,h1,r1,d1) { difference() { union() {
echo(str("linkage:",len,",",h0,",",r0,",",d0,",",h1,",",r1,",",d1));
   hull() { barAnchor(2.5*r0);
      cylinder(h=h0,r1=r0+.1,r2=r0-0.2,$fn=48); }
   translate([len,0,0]) { hull() { barAnchor(-2.5*r1);
      cylinder(h=h1,r1=r1+.1,r2=r1-.2,$fn=48); }}
   hull() {                cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6);
      translate([len,0,0]) cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6); }
   hull() {                   cylinder(h=h0-0.5,r1=2,r2=.6,$fn=6);
      translate([len-d1,0,0]) cylinder(h=h1-0.5,r1=2,r2=.6,$fn=6); }
   }
   drillHole(d0);
   translate([len,0,0]) drillHole(d1);
}}

// beefier version of a simple linkage, with same ends on both sides
module brace(len,h0,r0) {
r1=r0+1.7;
difference() { union() {
   difference() { hull() { cylinder(h=3,r1=r1+.1,r2=r1-.1,$fn=48);
      translate([len,0,0]) cylinder(h=3,r1=r1+.1,r2=r1-.1,$fn=48); }
      translate([1.5,0,-1.5]) hull() { cylinder(h=3,r1=r1-1.6,r2=r1-1.4,$fn=6);
             translate([len-1.5,0,0])  cylinder(h=3,r1=r1-1.6,r2=r1-1.4,$fn=6); }}

   translate([len,0,0])
   hull() { cylinder(h=h0,r1=r1+.2,r2=r1-.1,$fn=48);
      translate([-r1-4,0,2]) sphere(r=1,$fn=12); }
   hull() { cylinder(h=h0,r1=r1+.2,r2=r1-.1,$fn=48);
      translate([ r1+4,0,2]) sphere(r=1,$fn=12); }

   translate([0,0,h0/2]) hull() { scale([1,1,h0/2]) sphere(r=1,$fn=12);
            translate([len,0,0])  scale([1,1,h0/2]) sphere(r=1,$fn=12); }

   }
   drillHole(r0);
   translate([len,0,0]) drillHole(r0);
}}

module crankArm(len,h0,r0,d0,h1,r1,d1) { difference() {
  linkage(len,h0,r0,d0,h1,r1,d1);

  //// add little hole for "cotter-wire" on crank arm
  //translate([0,0,h0/2]) rotate(a=[90,0,0])
  //   cylinder(h=3*r0,r=.8,$fn=80,center=true);

  // for change to using standoffs as axle, counter sink axle screw
  translate([0,0,h0-1.5]) cylinder(h=2+.2,r1=rad4,r2=3.3,$fn=24);

  // try another countersink for spindle screw.
  translate([len,0,-1]) cylinder(h=2.2,r1=3.3,r2=rad4,$fn=24);
}}

include <JansenBED.scad>;

//============================================ Parts with brim/pads underneath

module BED_pad(left,base,perp) { union() { color("Cyan") hull() {
  translate([-left,0,0]) footpad(11);
  translate([base-left,0,0]) footpad(11);
  translate([0,perp,0]) footpad(13);}
  translate([0,0,.2]) imBED(left,base,perp);
}}
module bracedFoot_pad(left,base,perp) { union() { color("Cyan") hull() {
  translate([-left,0,0]) footpad(17);
  translate([0,perp,0]) footpad(11);
  translate([base-left,0,0]) footpad(13); }
  translate([0,0,.2]) bracedFoot(left,base,perp);
}}
module crankLink_pad(len,dFlat,rHole) { union() { color("Cyan") hull() {
   footpad(13);
   translate([len,0,0]) footpad(13); }
   translate([0,0,.2]) crankLink(len,dFlat,rHole);
}}
module monoBracedLinkage_pad(len) { union() { color("Cyan") hull() {
   footpad(15);
   translate([len,0,0]) footpad(13); }
   translate([0,0,.2]) monoBracedLinkage(len);
}}
module linkage_pad(len,h0,r0,d0,h1,r1,d1) { union() { color("Cyan") hull() {
   footpad(11);
   translate([len,0,0]) footpad(11); }
   translate([0,0,.2]) linkage(len,h0,r0,d0,h1,r1,d1);
}}
module brace_pad(len,h0,r0) { union() { color("Cyan") hull() { translate([len,0,0])
   footpad(r0+7);
   footpad(r0+7); }
   translate([0,0,.2]) brace(len,h0,r0);
}}
module linkage1_pad(len,h0,r0,d0,h1,r1,d1) { union() { color("Cyan") hull() {
   footpad(11);
   translate([len,0,0]) footpad(11); }
   translate([0,0,.2]) linkage1(len,h0,r0,d0,h1,r1,d1);
}}
module crankArm_pad(len,h0,r0,d0,h1,r1,d1) { union() { color("Cyan") hull() {
   footpad(11);
   translate([len,0,0]) footpad(11); }
   translate([0,0,.2]) crankArm(len,h0,r0,d0,h1,r1,d1);
}}
module mainBar_pad(x,y) { union() { color("Cyan") hull() {
  translate([-x,0,0]) footpad(12);
  translate([ x,0,0]) footpad(12);
  }
  translate([0,0,.2]) mainBar(x,y);
}}

//---------------------
module BED(dLeft,dBase,dPerp) { union() { rotate([0,0,50]) {
   translate([dBase*0.2,-3*Drad,0]) rotate([0,0,180]) mirror([1,0,0])
   BED_pad(dLeft,dBase,dPerp);
   BED_pad(dLeft,dBase,dPerp);
}}}
module feet(dLeft,dBase,dPerp) { union() {
   translate([dBase*0.15,-0.5*dPerp,0]) rotate([0,0,190]) mirror([1,0,0])
   bracedFoot_pad(dLeft,dBase,dPerp);
   bracedFoot_pad(dLeft,dBase,dPerp);
}}
module crankLinks() {
spc=6;
union() {
   translate([0,spc*3.2,0])
     crankLink_pad(CH,15,Hrad);
     crankLink_pad(CH,15,Hrad);
   rotate([0,0,180]) {
     translate([-CD-1.5*spc, spc*1.6,0]) crankLink_pad(CD,15,Drad);
     translate([-CD-1.5*spc,-spc*1.6,0]) crankLink_pad(CD,15,Drad); }

   // tight holes to glue to axle, not spin
   translate([5*spc,-3.2*spc,0])
     crankArm_pad(AC,acH0,acOR,acIR,acH1,acOR,acIR);
}}
module EFs(len) {
spc=6;
union() {
  translate([len-spc, 1.9*spc,0]) rotate([0,0,180]) monoBracedLinkage_pad(len);
  translate([len-spc,-1.9*spc,0]) rotate([0,0,180]) monoBracedLinkage_pad(len);
  translate([0,-3.8*spc,0]) monoBracedLinkage_pad(len);
  monoBracedLinkage_pad(len);
}}
module BHs(len,h0,r0,d0,h1,r1,d1) {
spc = 2*Brad;
union() {
  translate([spc*1.1, 1.6*spc,0]) linkage1_pad(len,h0,r0,d0,h1,r1,d1);
  translate([spc*1.1,-1.6*spc,0]) linkage1_pad(len,h0,r0,d0,h1,r1,d1);
  translate([ 0     ,-3.2*spc,0]) linkage1_pad(len,h0,r0,d0,h1,r1,d1);
                                  linkage1_pad(len,h0,r0,d0,h1,r1,d1);
}}

//=====================================================
use <spacers.scad>;

if      (PART=="BED"  ) {                   BED(DEleft,DE,DEperp); }
//else if (PART=="BEDa" ) {                 imBED(DEleft,DE,DEperp); }
//else if (PART=="BEDb" ) { mirror([1,0,0]) imBED(DEleft,DE,DEperp); }
else if (PART=="HipA" ) {                 BED1(DEleft,DE,DEperp); }
else if (PART=="HipB" ) { mirror([1,0,0]) BED1(DEleft,DE,DEperp); }
else if (PART=="jHipA" ) { imBEDj(DEleft,DE,DEperp); }
else if (PART=="jHipB" ) { mirror([1,0,0]) imBEDj(DEleft,DE,DEperp); }
else if (PART=="Feet" )                         feet(FGleft,FG,FGperp);
else if (PART=="FootA")
//difference() {
                  bracedFoot(FGleft,FG,FGperp);
  //  translate([0,0,18]) cube([200,200,20],center=true); }
else if (PART=="FootB") { mirror([1,0,0]) bracedFoot(FGleft,FG,FGperp); }
else if (PART=="crankLinks") crankLinks();
else if (PART=="CH"   ) crankLink(CH,15,Hrad); // build 2
else if (PART=="CD"   ) crankLink(CD,15,Drad); // build 2
else if (PART=="EF"   ) monoBracedLinkage(EF); // build 4
else if (PART=="EFs"  ) EFs(EF);
// make small end of BH a little shorter to make it easier to use a 1" screw for 'hamstirng' node
else if (PART=="BHs"  ) BHs(     BH,2.5*NodeHeight+1.5,Brad+1.8,BradFree,3.7,Hrad+2,rad4);
else if (PART=="BH"   ) linkage1(BH,2.5*NodeHeight+1.5,Brad+1.8,BradFree,3.7,Hrad+2,rad4); // build 4, glue them together with a rectangle if desired
else if (PART=="AC"   ) crankArm(AC,acH0,acOR,acIR,acH1,acOR,acIR);
else if (PART=="halfPulley") { union() { color("Cyan") footpad(pulleyR+7);
       translate([0,0,.2]) halfPulley(pulleyR,2.5,AradTight,-1); }}
else if (PART=="halfDrivePulley") { union() { color("Cyan") footpad(15);
       translate([0,0,.1]) halfPulley(8,2.5,1.5+.3,1+.3); }}
else if (PART=="pulley_pad") { union() { footpad(23); translate([0,0,.2])
                            pulley(18,5,rad4,0); }}
else if (PART=="pulley") {  pulley(18,5,rad4,0); }
else if (PART=="drivePulley_pad") { union() { footpad(15); translate([0,0,.2])
                                pulley(10,4,1.5+dHoleFuzz,1+dHoleFuzz); }}
else if (PART=="drivePulley") { pulley(10,4,1.5+dHoleFuzz,1+dHoleFuzz); }
else if (PART=="mainBar") {  mainBar(Bx,Ay); }
else if (PART=="main") { mainBar_pad(Bx,Ay); }
else if (PART=="braceBar") {  brace(2*Bx,8,Brad); }
else if (PART=="brace") { brace_pad(2*Bx,8,Brad); }
else if (PART=="spacers") { union(){ spacers(NodeHeight/2,Bhole+3,Brad);
   translate([0,-7.5*LinkRad*1.414+1,0]) spacers(NodeHeight/2,LinkRad,rad4); }}
//else if (PART=="demo") { //show all unique parts
else {
   mainBar(Bx,Ay);
   #translate([0,Ay,20]) pulley(18,5,rad4,0);
   translate([0,-50,0])  pulley(10,4,1.5+.3,1+.3);
   translate([ 50, 30,0]) BED1(DEleft,DE,DEperp);//imBED(DEleft,DE,DEperp);
   translate([-26, 44,0]) rotate([0,0,180]) bracedFoot(FGleft,FG,FGperp);
   translate([-12,-16,0]) crankLink(CD,15,Drad);
   translate([-36,-28,0]) crankLink(CH,15,Hrad);
   translate([-73,-15,0]) monoBracedLinkage(EF);
   translate([-60, 15,0]) crankArm(AC,acH0,acOR,acIR,acH1,acOR,acIR);

   translate([ 25, 15,0]) linkage1(BH,2.5*NodeHeight,Brad+1.8,BradFree,ForkHeight,Hrad+2,rad4);
   translate([40,-42,0]) rotate([0,0,50]) brace(2*Bx,8,Brad);
}