added wire channel in case top (had to manually cut with last version)

// Serial DMM adapter case
// designed to fit an Arduino nano clone and a DB-9 male plug
//
// Copyright (C) 2016 Theodore C. Yapo

layout = "printing";
//layout = "exploded";

board_width = 18.5;
board_length = 44.5;
board_thickness = 1.85;
usb_lip = 2;
usb_height = 4.25;
usb_width = 8;
usb_length = 9;

module nano_board()
{
  translate([-board_length/2, -board_width/2, 0]){
    color("blue") cube([board_length, board_width, board_thickness]);
  }
  translate([-board_length/2-2.5, -usb_width/2, board_thickness]){
    color([0.85, 0.85, 0.85]) cube([usb_length, usb_width, usb_height]);
  }
}

db9_hole_spacing = 25;
module db9_profile()
{
  corner_r = 3;
  top_w = 19.5;
  bottom_w = 17.5;
  height = 9.5;
  length = 7;
  back_length = 9;
  flange_w = 33.5;
  flange_h = 20;
  flange_r = 1;
  flange_thickness = 1.25;
  fn = 13;
  epsilon = 0.1;

  // pin shroud
  translate([0, 0, -back_clearance]){
    hull(){
      translate([+(-top_w/2 + corner_r), +(-height/2 + corner_r), 0]){
        cylinder($fn = fn, r = corner_r, h = length);
      }
      translate([+(-bottom_w/2 + corner_r), -(-height/2 + corner_r), 0]){
        cylinder($fn = fn, r = corner_r, h = length);
      }
      translate([-(-bottom_w/2 + corner_r), -(-height/2 + corner_r), 0]){
        cylinder($fn = fn, r = corner_r, h = length);
      }
      translate([-(-top_w/2 + corner_r), +(-height/2 + corner_r), 0]){
        cylinder($fn = fn, r = corner_r, h = length);
      }
    }
  }

  // back body
  b_corner_r = 3;
  b_top_w = 22;
  b_bottom_w = 19;
  b_height = 12;
  translate([0, 0, -back_clearance]){
    hull(){
      translate([+(-b_top_w/2 + b_corner_r),
                 +(-b_height/2 + b_corner_r),
                 -back_length-epsilon]){
        cylinder($fn = fn, r = b_corner_r, h = back_length+2*epsilon);
      }
      translate([+(-b_bottom_w/2 + b_corner_r),
                 -(-b_height/2 + b_corner_r),
                 -back_length-epsilon]){
        cylinder($fn = fn, r = b_corner_r, h = back_length+2*epsilon);
      }
      translate([-(-b_bottom_w/2 + b_corner_r),
                 -(-b_height/2 + b_corner_r),
                 -back_length-epsilon]){
        cylinder($fn = fn, r = b_corner_r, h = back_length+2*epsilon);
      }
      translate([-(-b_top_w/2 + b_corner_r),
                 +(-b_height/2 + b_corner_r),
                 -back_length-epsilon]){
        cylinder($fn = fn, r = b_corner_r, h = back_length+2*epsilon);
      }
    }
  }

  // flange
  hull(){
    translate([+(-flange_w/2 + flange_r), +(-flange_h/2 + flange_r), 0]){
      cylinder($fn = fn, r = flange_r, h = flange_thickness);
    }
    translate([+(-flange_w/2 + flange_r), -(-flange_h/2 + flange_r), 0]){
      cylinder($fn = fn, r = flange_r, h = flange_thickness);
    }
    translate([-(-flange_w/2 + flange_r), +(-flange_h/2 + flange_r), 0]){
      cylinder($fn = fn, r = flange_r, h = flange_thickness);
    }
    translate([-(-flange_w/2 + flange_r), -(-flange_h/2 + flange_r), 0]){
      cylinder($fn = fn, r = flange_r, h = flange_thickness);
    }
  }

}

height = 20;
length = 64;
width = 22;
board_lip = 2;
connector_width = 40;
connector_length = 18;
connector_recess = 5;
connector_height = 13;
bulge_length = 10;
bottom_thickness = 3;
nut_dist = 6;
screw_hole_d = 3.25;
screw_hole_x = length/2 - connector_length + 5;
screw_hole_y = (connector_width + width) / 4;

module case_bottom()
{
  difference(){
    union(){
      // body
      translate([-length/2, -width/2, 0]){
        cube([length, width, height/2]);
      }
      // DB9 connector bulge
      translate([length/2 - connector_length, -connector_width/2, 0]){
        cube([connector_length, connector_width, connector_height]);
      }
      // screw clamp bulge
      translate([-length/2, -connector_width/2, 0]){
        cube([bulge_length, connector_width, height/2]);
      }
    }

    // wire channel
    translate([-length/2 + usb_lip,
               -board_width/2 + board_lip,
               height/2]){
      cube([length - board_lip,
            board_width - 2*board_lip,
            height/2]);
    }

    // below-board hollow
    translate([-length/2 + usb_lip,
               -board_width/2 + board_lip,
               bottom_thickness]){
      cube([board_length - board_lip,
            board_width - 2*board_lip,
            height/2]);
    }
    // board recess
    translate([-length/2 + usb_lip,
               -board_width/2,
               height/2 - board_thickness]){
      cube([board_length,
            board_width,
            height/2]);
    }
    // DB9 opening
    translate([length/2-connector_recess, 0, height/2]){
      rotate([0, 90, 0]){
        rotate([0, 0, -90]){
          db9_profile();
        }
      }
    }
    // nut slots
    translate([length/2-nut_dist, -db9_hole_spacing/2, height/2]){
      rotate([0, -90, 0]){
        hull(){
          cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          translate([20, 0, 0]){
            cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          }
        }
      }
    }
    translate([length/2-nut_dist, +db9_hole_spacing/2, height/2]){
      rotate([0, -90, 0]){
        hull(){
          cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          translate([20, 0, 0]){
            cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          }
        }
      }
    }

    // screw holes
    epsilon = 1;
    screw_hole_d = 3.25;
    screw_hole_x1 = length/2 - connector_length + 5;
    screw_hole_y = (connector_width + width) / 4;
    translate([screw_hole_x1, -screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    translate([screw_hole_x1, +screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }

    screw_hole_x2 = -length/2 + 5;
    translate([screw_hole_x2, -screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    translate([screw_hole_x2, +screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }

    // DB connector screw holes
    translate([length/2 -15,  -db9_hole_spacing/2, height/2]){
      rotate([0, 90, 0]){
        cylinder($fn = 8, d = screw_hole_d, h = height);
      }
    }
    translate([length/2 -15,  +db9_hole_spacing/2, height/2]){
      rotate([0, 90, 0]){
        cylinder($fn = 8, d = screw_hole_d, h = height);
      }
    }

  }
}

module case_top()
{
  epsilon = 1;

  difference(){
    union(){
      // body
      translate([-length/2, -width/2, 0]){
        cube([length, width, height/2]);
      }
      // DB9 connector bulge
      translate([length/2 - connector_length, -connector_width/2, 0]){
        cube([connector_length, connector_width, height-connector_height]);
      }
      // screw clamp bulge
      translate([-length/2, -connector_width/2, 0]){
        cube([bulge_length, connector_width, height/2]);
      }
    }

    // DB9 connector bulge trim
    tol = 0.5;
    translate([length/2 - connector_length - tol,
               -connector_width/2,
               height-connector_height]){
      cube([connector_length+epsilon+tol, connector_width, connector_height]);
    }

    // wire channel
    translate([-length/2 + usb_lip,
               -board_width/2 + board_lip,
               height - connector_height]){
      cube([length - board_lip,
            board_width - 2*board_lip,
            height/2]);
    }

    // below-board hollow
    translate([-length/2 + usb_lip,
               -board_width/2 + board_lip,
               bottom_thickness]){
      cube([board_length - board_lip,
            board_width - 2*board_lip,
            height/2]);
    }

    // DB9 opening
    translate([length/2-connector_recess, 0, height/2]){
      rotate([0, 90, 0]){
        rotate([0, 0, 90]){
          db9_profile();
        }
      }
    }

    // usb slot
    translate([-length/2-5, -usb_width/2, height/2-usb_height]){
      cube([10, usb_width, usb_height+epsilon]);
    }

    // nut slots
    translate([length/2-nut_dist, -db9_hole_spacing/2, height/2]){
      rotate([0, -90, 0]){
        hull(){
          cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          translate([20, 0, 0]){
            cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          }
        }
      }
    }
    translate([length/2-nut_dist, +db9_hole_spacing/2, height/2]){
      rotate([0, -90, 0]){
        hull(){
          cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          translate([20, 0, 0]){
            cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          }
        }
      }
    }

    // screw holes
    epsilon = 1;
    screw_hole_d = 3.25;
    screw_hole_x1 = length/2 - connector_length + 5;
    screw_hole_y = (connector_width + width) / 4;
    translate([screw_hole_x1, -screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    translate([screw_hole_x1, +screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    screw_hole_x2 = -length/2 + 5;
    translate([screw_hole_x2, -screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    translate([screw_hole_x2, +screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
  }
}

if (layout == "exploded"){
  exploded_dist = 10;

  case_bottom();
  translate([0, 0, 4*exploded_dist]){
    mirror([0, 0, 1]){
      case_top();
    }
  }
  translate([-(length - board_length)/2 + usb_lip,
             0,
             height/2 - board_thickness + exploded_dist]){
    nano_board();
  }
  translate([length/2-connector_recess + exploded_dist,
             0,
             height/2 + exploded_dist]){
    rotate([0, 90, 0]){
      rotate([0, 0, -90]){
        color([0.85, 0.85, 0.85]) db9_profile();
      }
    }
  }
}

if (layout == "printing"){
  s = 25;

  translate([0, +s, 0]){
    case_bottom();
  }
  translate([0, -s, 0]){
    rotate([0, 0, 180]){
      case_top();
    }
  }
}

// Serial DMM adapter case
// designed to fit an Arduino nano clone and a DB-9 male plug
//
// Copyright (C) 2016 Theodore C. Yapo

layout = "printing";
//layout = "exploded";

board_width = 18.5;
board_length = 44.5;
board_thickness = 1.85;
usb_lip = 2;
usb_height = 4.25;
usb_width = 8;
usb_length = 9;

module nano_board()
{
  translate([-board_length/2, -board_width/2, 0]){
    color("blue") cube([board_length, board_width, board_thickness]);
  }
  translate([-board_length/2-2.5, -usb_width/2, board_thickness]){
    color([0.85, 0.85, 0.85]) cube([usb_length, usb_width, usb_height]);
  }
}

db9_hole_spacing = 25;
module db9_profile()
{
  corner_r = 3;
  top_w = 19.5;
  bottom_w = 17.5;
  height = 9.5;
  length = 7;
  back_length = 9;
  flange_w = 33.5;
  flange_h = 20;
  flange_r = 1;
  flange_thickness = 1.25;
  fn = 13;
  epsilon = 0.1;

  // pin shroud
  translate([0, 0, -back_clearance]){
    hull(){
      translate([+(-top_w/2 + corner_r), +(-height/2 + corner_r), 0]){
        cylinder($fn = fn, r = corner_r, h = length);
      }
      translate([+(-bottom_w/2 + corner_r), -(-height/2 + corner_r), 0]){
        cylinder($fn = fn, r = corner_r, h = length);
      }
      translate([-(-bottom_w/2 + corner_r), -(-height/2 + corner_r), 0]){
        cylinder($fn = fn, r = corner_r, h = length);
      }
      translate([-(-top_w/2 + corner_r), +(-height/2 + corner_r), 0]){
        cylinder($fn = fn, r = corner_r, h = length);
      }
    }
  }

  // back body
  b_corner_r = 3;
  b_top_w = 22;
  b_bottom_w = 19;
  b_height = 12;
  translate([0, 0, -back_clearance]){
    hull(){
      translate([+(-b_top_w/2 + b_corner_r),
                 +(-b_height/2 + b_corner_r),
                 -back_length-epsilon]){
        cylinder($fn = fn, r = b_corner_r, h = back_length+2*epsilon);
      }
      translate([+(-b_bottom_w/2 + b_corner_r),
                 -(-b_height/2 + b_corner_r),
                 -back_length-epsilon]){
        cylinder($fn = fn, r = b_corner_r, h = back_length+2*epsilon);
      }
      translate([-(-b_bottom_w/2 + b_corner_r),
                 -(-b_height/2 + b_corner_r),
                 -back_length-epsilon]){
        cylinder($fn = fn, r = b_corner_r, h = back_length+2*epsilon);
      }
      translate([-(-b_top_w/2 + b_corner_r),
                 +(-b_height/2 + b_corner_r),
                 -back_length-epsilon]){
        cylinder($fn = fn, r = b_corner_r, h = back_length+2*epsilon);
      }
    }
  }

  // flange
  hull(){
    translate([+(-flange_w/2 + flange_r), +(-flange_h/2 + flange_r), 0]){
      cylinder($fn = fn, r = flange_r, h = flange_thickness);
    }
    translate([+(-flange_w/2 + flange_r), -(-flange_h/2 + flange_r), 0]){
      cylinder($fn = fn, r = flange_r, h = flange_thickness);
    }
    translate([-(-flange_w/2 + flange_r), +(-flange_h/2 + flange_r), 0]){
      cylinder($fn = fn, r = flange_r, h = flange_thickness);
    }
    translate([-(-flange_w/2 + flange_r), -(-flange_h/2 + flange_r), 0]){
      cylinder($fn = fn, r = flange_r, h = flange_thickness);
    }
  }

}

height = 20;
length = 64;
width = 22;
board_lip = 2;
connector_width = 40;
connector_length = 18;
connector_recess = 5;
connector_height = 13;
bulge_length = 10;
bottom_thickness = 3;
nut_dist = 6;
screw_hole_d = 3.25;
screw_hole_x = length/2 - connector_length + 5;
screw_hole_y = (connector_width + width) / 4;

module case_bottom()
{
  difference(){
    union(){
      // body
      translate([-length/2, -width/2, 0]){
        cube([length, width, height/2]);
      }
      // DB9 connector bulge
      translate([length/2 - connector_length, -connector_width/2, 0]){
        cube([connector_length, connector_width, connector_height]);
      }
      // screw clamp bulge
      translate([-length/2, -connector_width/2, 0]){
        cube([bulge_length, connector_width, height/2]);
      }
    }

    // wire channel
    translate([-length/2 + usb_lip,
               -board_width/2 + board_lip,
               height/2]){
      cube([length - board_lip,
            board_width - 2*board_lip,
            height/2]);
    }

    // below-board hollow
    translate([-length/2 + usb_lip,
               -board_width/2 + board_lip,
               bottom_thickness]){
      cube([board_length - board_lip,
            board_width - 2*board_lip,
            height/2]);
    }
    // board recess
    translate([-length/2 + usb_lip,
               -board_width/2,
               height/2 - board_thickness]){
      cube([board_length,
            board_width,
            height/2]);
    }
    // DB9 opening
    translate([length/2-connector_recess, 0, height/2]){
      rotate([0, 90, 0]){
        rotate([0, 0, -90]){
          db9_profile();
        }
      }
    }
    // nut slots
    translate([length/2-nut_dist, -db9_hole_spacing/2, height/2]){
      rotate([0, -90, 0]){
        hull(){
          cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          translate([20, 0, 0]){
            cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          }
        }
      }
    }
    translate([length/2-nut_dist, +db9_hole_spacing/2, height/2]){
      rotate([0, -90, 0]){
        hull(){
          cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          translate([20, 0, 0]){
            cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          }
        }
      }
    }

    // screw holes
    epsilon = 1;
    screw_hole_d = 3.25;
    screw_hole_x1 = length/2 - connector_length + 5;
    screw_hole_y = (connector_width + width) / 4;
    translate([screw_hole_x1, -screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    translate([screw_hole_x1, +screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }

    screw_hole_x2 = -length/2 + 5;
    translate([screw_hole_x2, -screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    translate([screw_hole_x2, +screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }

    // DB connector screw holes
    translate([length/2 -15,  -db9_hole_spacing/2, height/2]){
      rotate([0, 90, 0]){
        cylinder($fn = 8, d = screw_hole_d, h = height);
      }
    }
    translate([length/2 -15,  +db9_hole_spacing/2, height/2]){
      rotate([0, 90, 0]){
        cylinder($fn = 8, d = screw_hole_d, h = height);
      }
    }

  }
}

module case_top()
{
  epsilon = 1;

  difference(){
    union(){
      // body
      translate([-length/2, -width/2, 0]){
        cube([length, width, height/2]);
      }
      // DB9 connector bulge
      translate([length/2 - connector_length, -connector_width/2, 0]){
        cube([connector_length, connector_width, height-connector_height]);
      }
      // screw clamp bulge
      translate([-length/2, -connector_width/2, 0]){
        cube([bulge_length, connector_width, height/2]);
      }
    }

    // DB9 connector bulge trim
    tol = 0.5;
    translate([length/2 - connector_length - tol,
               -connector_width/2,
               height-connector_height]){
      cube([connector_length+epsilon+tol, connector_width, connector_height]);
    }

    // below-board hollow
    translate([-length/2 + usb_lip,
               -board_width/2 + board_lip,
               bottom_thickness]){
      cube([board_length - board_lip,
            board_width - 2*board_lip,
            height/2]);
    }

    // DB9 opening
    translate([length/2-connector_recess, 0, height/2]){
      rotate([0, 90, 0]){
        rotate([0, 0, 90]){
          db9_profile();
        }
      }
    }

    // usb slot
    translate([-length/2-5, -usb_width/2, height/2-usb_height]){
      cube([10, usb_width, usb_height+epsilon]);
    }

    // nut slots
    translate([length/2-nut_dist, -db9_hole_spacing/2, height/2]){
      rotate([0, -90, 0]){
        hull(){
          cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          translate([20, 0, 0]){
            cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          }
        }
      }
    }
    translate([length/2-nut_dist, +db9_hole_spacing/2, height/2]){
      rotate([0, -90, 0]){
        hull(){
          cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          translate([20, 0, 0]){
            cylinder($fn = 6, d = 6.25 / cos(30), h = 3);
          }
        }
      }
    }

    // screw holes
    epsilon = 1;
    screw_hole_d = 3.25;
    screw_hole_x1 = length/2 - connector_length + 5;
    screw_hole_y = (connector_width + width) / 4;
    translate([screw_hole_x1, -screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    translate([screw_hole_x1, +screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    screw_hole_x2 = -length/2 + 5;
    translate([screw_hole_x2, -screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
    translate([screw_hole_x2, +screw_hole_y, -epsilon]){
      cylinder($fn = 8, d = screw_hole_d, h = height);
    }
  }
}

if (layout == "exploded"){
  exploded_dist = 10;

  case_bottom();
  translate([0, 0, 4*exploded_dist]){
    mirror([0, 0, 1]){
      case_top();
    }
  }
  translate([-(length - board_length)/2 + usb_lip,
             0,
             height/2 - board_thickness + exploded_dist]){
    nano_board();
  }
  translate([length/2-connector_recess + exploded_dist,
             0,
             height/2 + exploded_dist]){
    rotate([0, 90, 0]){
      rotate([0, 0, -90]){
        color([0.85, 0.85, 0.85]) db9_profile();
      }
    }
  }
}

if (layout == "printing"){
  s = 25;

  translate([0, +s, 0]){
    case_bottom();
  }
  translate([0, -s, 0]){
    rotate([0, 0, 180]){
      case_top();
    }
  }
}


y/idler: minor debug tweak

y/idler: minor debug tweak

include <y-idler.h>

include <thing_libutils/materials.scad>
use <thing_libutils/screws.scad>

module yaxis_idler(part)
{
    tighten_screw_dia_outer = yaxis_idler_mount_tightscrew_dia*4;
    mount_screw_dist = (yidler_w/2+yaxis_idler_mount_thread_dia*3)*1.3;

    if(part==U)
    {
        difference()
        {
            yaxis_idler(part="pos");
            yaxis_idler(part="neg");
        }
        yaxis_idler(part="vit");
    }
    else if(part=="pos")
    material(Mat_Plastic)
    {
        // front plate
        tx(-extrusion_size/2)
        rcubea(
            size=[yaxis_idler_mount_thickness, yidler_mount_width, extrusion_size],
            align=-X,
            extra_size=Z*yaxis_idler_mount_thickness,
            extra_align=Z
            );

        // top mount plate
        translate([-yaxis_idler_mount_thickness,0,extrusion_size/2])
        rcubea(
            size=[extrusion_size, yidler_mount_width, yaxis_idler_mount_thickness],
            align=Z,
            extra_size=[yaxis_idler_mount_thickness,0,0],
            extra_align=X
            );

        intersection()
        {
            tz(extrusion_size/2)
            cubea([100, yidler_mount_width, 100], align=Z);

            hull()
            {
                for(y=[-1,1])
                ty(y*yaxis_idler_tightscrew_dist)
                tx(-yaxis_idler_mount_thickness)
                tz(extrusion_size/2)
                {
                    translate([yaxis_idler_mount_thickness/2,0,yaxis_belt_path_offset_z])
                    rcylindera(
                        h=extrusion_size+yaxis_idler_mount_thickness,
                        d=tighten_screw_dia_outer,
                        align=N,
                        orient=X
                        );
                    rcubea(
                        size=[extrusion_size, mount_screw_dist-yaxis_idler_mount_tightscrew_dia*3, yaxis_idler_mount_thickness],
                        align=Z,
                        extra_size=[yaxis_idler_mount_thickness,0,0],
                        extra_align=X
                        );
                }
            }

        }

    }
    else if(part=="neg")
    {
        // top/vertical mount screws (to extrusion)
        translate([0,0,extrusion_size/2+yaxis_idler_mount_thickness])
        for(y=[-1,1])
        ty(y*mount_screw_dist/2)
        screw_cut(nut=extrusion_nut, head="button", h=yaxis_idler_mount_thickness+5*mm, with_nut=false, orient=-Z, align=-Z);

        // mount screws for pulley block
        for(y=[-1,1])
        tx(-extrusion_size/2-yaxis_idler_mount_thickness)
        ty(y*yaxis_idler_tightscrew_dist)
        tz(extrusion_size/2+yaxis_belt_path_offset_z)
        screw_cut(yaxis_idler_mount_tightscrew_hexnut, head_embed=false, h=extrusion_size+yaxis_idler_mount_thickness+10*mm, with_nut=false, orient=X, align=X);

        // pulley block adjustment screw
        tx(-extrusion_size/2-yaxis_idler_mount_thickness)
        tz(extrusion_size/2+yaxis_belt_path_offset_z)
        tx(extrusion_size/2)
        tx(yaxis_idler_mount_thickness/2)
        t(yaxis_idler_mount_adjustscrew_offset)
        screw_cut(yaxis_idler_mount_adjustscrew_hexnut, head_embed=false, h=extrusion_size/2+yaxis_idler_mount_thickness, with_nut=false, orient=X, align=X);

        // front/horizontal mount screws (to extrusion)
        tx(-extrusion_size/2)
        tx(-yaxis_idler_mount_thickness)
        for(y=[-1,1])
        ty(y*(yaxis_idler_mount_thread_dia*2.5))
        screw_cut(nut=extrusion_nut, head="button", h=yaxis_idler_mount_thickness+5*mm, with_nut=false, orient=X, align=X);
    }
}

module yaxis_idler_pulleyblock(part, show_pulley=false)
{
    h = yaxis_idler_pulley_h + 3*mm*2;
    d=yaxis_idler_mount_tightscrew_hexnut_dia*2;

    if(part==U)
    {
        difference()
        {
            yaxis_idler_pulleyblock(part="pos");
            yaxis_idler_pulleyblock(part="neg");
        }
        %yaxis_idler_pulleyblock(part="vit");
    }
    else if(part=="pos")
    material(Mat_Plastic)
    {
        hull()
        {
            // idler
            tz(h/2)
            rcylindera(d=yaxis_idler_pulley_thread_dia+15*mm, h=h, orient=-Z, align=-Z);

            // tension screws
            tx(-yaxis_idler_pulleyblock_supportsize/2-yaxis_idler_pulley_tight_len)
            for(y=[-1,1])
            ty(y*yaxis_idler_tightscrew_dist)
            rcubea([d,d,yaxis_idler_pulley_tight_len], orient=X, align=X);

            // adjustment screw
            tx(-yaxis_idler_pulleyblock_supportsize/2-yaxis_idler_pulley_tight_len)
            t(yaxis_idler_mount_adjustscrew_offset)
            rcylindera(d=yaxis_idler_mount_adjustscrew_hexnut_dia*2, orient=X, align=X);
        }
    }
    else if(part=="neg")
    {
        // pulley cutout
        tx(-3*mm)
        cubea(
            size=[yaxis_idler_pulley_outer_d, yaxis_idler_pulley_outer_d*3, yaxis_idler_pulley_h+0.5],
            align=N,
            extra_size=[20*mm,0,0], extra_align=X
            );

        // pulley screw
        tz(h/2)
        screw_cut(yaxis_idler_pulley_nut, head="button", h=h+5*mm, orient=-Z, align=-Z);

        // tension screws
        for(y=[-1,1])
        tx(-yaxis_idler_pulleyblock_supportsize/2-yaxis_idler_pulley_tight_len)
        ty(y*yaxis_idler_tightscrew_dist)
        screw_cut(yaxis_idler_mount_tightscrew_hexnut, head_embed=false, nut_offset=2*mm, h=yaxis_idler_pulley_tight_len, orient=X, align=X);

        // adjustment screw
        tx(-yaxis_idler_pulleyblock_supportsize/2-yaxis_idler_pulley_tight_len)
        tx(yaxis_idler_pulley_tight_len/2)
        t(yaxis_idler_mount_adjustscrew_offset)
        nut_trap_cut(nut=yaxis_idler_mount_adjustscrew_hexnut, head="button", cut_screw=true, screw_l=20*mm, trap_axis=-Z, orient=-X);
    }
    else if(part=="vit")
    {
        pulley(pulley_2GT_20T_idler);
    }

}

module part_y_idler()
{
    attach([N, -Z], yaxis_idler_conn)
    {
        yaxis_idler();
    }
}

module part_y_idler_pulleyblock()
{
    attach([N, -X], yaxis_idler_pulleyblock_conn_print)
    {
        yaxis_idler_pulleyblock(show_pulley=false);
    }
}

/*yaxis_idler();*/
/*yaxis_idler_pulleyblock();*/

/*attach([N,-X], yaxis_idler_conn)*/
/*{*/
    /*yaxis_idler();*/
    /*attach(yaxis_idler_conn_pulleyblock, yaxis_idler_pulleyblock_conn)*/
    /*{*/
        /*yaxis_idler_pulleyblock(show_pulley=true);*/
    /*}*/
/*}*/

include <y-idler.h>

include <thing_libutils/materials.scad>
use <thing_libutils/screws.scad>

module yaxis_idler(part)
{
    tighten_screw_dia_outer = yaxis_idler_mount_tightscrew_dia*4;
    mount_screw_dist = (yidler_w/2+yaxis_idler_mount_thread_dia*3)*1.3;

    if(part==U)
    {
        difference()
        {
            yaxis_idler(part="pos");
            yaxis_idler(part="neg");
        }
        yaxis_idler(part="vit");
    }
    else if(part=="pos")
    material(Mat_Plastic)
    {
        // front plate
        tx(-extrusion_size/2)
        rcubea(
            size=[yaxis_idler_mount_thickness, yidler_mount_width, extrusion_size],
            align=-X,
            extra_size=Z*yaxis_idler_mount_thickness,
            extra_align=Z
            );

        // top mount plate
        translate([-yaxis_idler_mount_thickness,0,extrusion_size/2])
        rcubea(
            size=[extrusion_size, yidler_mount_width, yaxis_idler_mount_thickness],
            align=Z,
            extra_size=[yaxis_idler_mount_thickness,0,0],
            extra_align=X
            );

        intersection()
        {
            tz(extrusion_size/2)
            cubea([100, yidler_mount_width, 100], align=Z);

            hull()
            {
                for(y=[-1,1])
                ty(y*yaxis_idler_tightscrew_dist)
                tx(-yaxis_idler_mount_thickness)
                tz(extrusion_size/2)
                {
                    translate([yaxis_idler_mount_thickness/2,0,yaxis_belt_path_offset_z])
                    rcylindera(
                        h=extrusion_size+yaxis_idler_mount_thickness,
                        d=tighten_screw_dia_outer,
                        align=N,
                        orient=X
                        );
                    rcubea(
                        size=[extrusion_size, mount_screw_dist-yaxis_idler_mount_tightscrew_dia*3, yaxis_idler_mount_thickness],
                        align=Z,
                        extra_size=[yaxis_idler_mount_thickness,0,0],
                        extra_align=X
                        );
                }
            }

        }

    }
    else if(part=="neg")
    {
        // top/vertical mount screws (to extrusion)
        translate([0,0,extrusion_size/2+yaxis_idler_mount_thickness])
        for(y=[-1,1])
        ty(y*mount_screw_dist/2)
        screw_cut(nut=extrusion_nut, head="button", h=yaxis_idler_mount_thickness+5*mm, with_nut=false, orient=-Z, align=-Z);

        // mount screws for pulley block
        for(y=[-1,1])
        tx(-extrusion_size/2-yaxis_idler_mount_thickness)
        ty(y*yaxis_idler_tightscrew_dist)
        tz(extrusion_size/2+yaxis_belt_path_offset_z)
        screw_cut(yaxis_idler_mount_tightscrew_hexnut, head_embed=false, h=extrusion_size+yaxis_idler_mount_thickness+10*mm, with_nut=false, orient=X, align=X);

        // pulley block adjustment screw
        tx(-extrusion_size/2-yaxis_idler_mount_thickness)
        tz(extrusion_size/2+yaxis_belt_path_offset_z)
        tx(extrusion_size/2)
        tx(yaxis_idler_mount_thickness/2)
        t(yaxis_idler_mount_adjustscrew_offset)
        screw_cut(yaxis_idler_mount_adjustscrew_hexnut, head_embed=false, h=extrusion_size/2+yaxis_idler_mount_thickness, with_nut=false, orient=X, align=X);

        // front/horizontal mount screws (to extrusion)
        tx(-extrusion_size/2)
        tx(-yaxis_idler_mount_thickness)
        for(y=[-1,1])
        ty(y*(yaxis_idler_mount_thread_dia*2.5))
        screw_cut(nut=extrusion_nut, head="button", h=yaxis_idler_mount_thickness+5*mm, with_nut=false, orient=X, align=X);
    }
}

module yaxis_idler_pulleyblock(part, show_pulley=false)
{
    h = yaxis_idler_pulley_h + 3*mm*2;
    d=yaxis_idler_mount_tightscrew_hexnut_dia*2;

    if(part==U)
    {
        difference()
        {
            yaxis_idler_pulleyblock(part="pos");
            yaxis_idler_pulleyblock(part="neg");
        }
        %yaxis_idler_pulleyblock(part="vit");
    }
    else if(part=="pos")
    material(Mat_Plastic)
    {
        hull()
        {
            // idler
            tz(h/2)
            rcylindera(d=yaxis_idler_pulley_thread_dia+15*mm, h=h, orient=-Z, align=-Z);

            // tension screws
            tx(-yaxis_idler_pulleyblock_supportsize/2-yaxis_idler_pulley_tight_len)
            for(y=[-1,1])
            ty(y*yaxis_idler_tightscrew_dist)
            rcubea([d,d,yaxis_idler_pulley_tight_len], orient=X, align=X);

            // adjustment screw
            tx(-yaxis_idler_pulleyblock_supportsize/2-yaxis_idler_pulley_tight_len)
            t(yaxis_idler_mount_adjustscrew_offset)
            rcylindera(d=yaxis_idler_mount_adjustscrew_hexnut_dia*2, orient=X, align=X);
        }
    }
    else if(part=="neg")
    {
        // pulley cutout
        tx(-3*mm)
        cubea(
            size=[yaxis_idler_pulley_outer_d, yaxis_idler_pulley_outer_d*3, yaxis_idler_pulley_h+0.5],
            align=N,
            extra_size=[20*mm,0,0], extra_align=X
            );

        // pulley screw
        tz(h/2)
        screw_cut(yaxis_idler_pulley_nut, head="button", h=h+5*mm, orient=-Z, align=-Z);

        // tension screws
        for(y=[-1,1])
        tx(-yaxis_idler_pulleyblock_supportsize/2-yaxis_idler_pulley_tight_len)
        ty(y*yaxis_idler_tightscrew_dist)
        screw_cut(yaxis_idler_mount_tightscrew_hexnut, head_embed=false, nut_offset=2*mm, h=yaxis_idler_pulley_tight_len, orient=X, align=X);

        // adjustment screw
        tx(-yaxis_idler_pulleyblock_supportsize/2-yaxis_idler_pulley_tight_len)
        tx(yaxis_idler_pulley_tight_len/2)
        t(yaxis_idler_mount_adjustscrew_offset)
        nut_trap_cut(nut=yaxis_idler_mount_adjustscrew_hexnut, head="button", cut_screw=true, screw_l=20*mm, trap_axis=-Z, orient=-X);
    }
    else if(part=="vit")
    {
        pulley(pulley_2GT_20T_idler);
    }

}

module part_y_idler()
{
    attach([N, -Z], yaxis_idler_conn)
    {
        yaxis_idler();
    }
}

module part_y_idler_pulleyblock()
{
    attach([N, -X], yaxis_idler_pulleyblock_conn_print)
    {
        yaxis_idler_pulleyblock(show_pulley=false);
    }
}

/*yaxis_idler();*/
/*yaxis_idler_pulleyblock();*/

/*print_yaxis_idler();*/
/*print_yaxis_idler_pulleyblock();*/

/*attach([N,[-1,0,0]], yaxis_idler_conn)*/
/*{*/
    /*yaxis_idler();*/
    /*attach(yaxis_idler_conn_pulleyblock, yaxis_idler_pulleyblock_conn)*/
    /*{*/
        /*yaxis_idler_pulleyblock(show_pulley=true);*/
    /*}*/
/*}*/


todo: arm spacers and elbow screw holes

todo: arm spacers and elbow screw holes

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

// global rendering parameters
$fn = 24;

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

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

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

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

// shoulder base
color([.7, .7, 1])
    shoulderBase(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// shoulder lower stepper
rotate([0, 180, 0])
    translate([-8, 0, 10])
        StepMotor28BYJ();
// lower shoulder bearing
translate([0, 0, shoulderBaseHeight + bearingStep])
    %bearing6807_2RS();
// shoulder top
color([.6, .6, .9])
    translate([0, 0, 2 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep)])
    rotate([180, 0, 0])
        shoulderBase(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// upper shoulder bearing
translate([0, 0, shoulderBaseHeight + (3 * bearing6807_2RS_B) + (7 * bearingStep)])
    %bearing6807_2RS();
// shoulder upper stepper
rotate([0, 0, 180])
    translate([-8, 0, 10 + 2 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep)])
        StepMotor28BYJ();
// shoulder spacers
color([.7, .6, .2])
shoulderSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
color([.7, .6, .2])
translate([baseDeckExtension / 3, 0, 0])
shoulderSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
// end shoulder

// lower arm including the shoulder - arm joint
//render()
color([1, .7, .7])
    translate([0, 0, shoulderBaseHeight + bearing6807_2RS_B])
        armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
// upper arm
//render()
color([.9, .7, .7])
    translate([0, 0, shoulderBaseHeight + ( 2*bearing6807_2RS_B) + (12 * bearingStep) - (.5 * bearingStep)])
        rotate([180, 0, 0])
            armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
// elbow joint pieces
// lower bearing
translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + bearingStep])
    %bearing6807_2RS();
// arm upper stepper
translate([-armLength + 8, 0, shoulderBaseHeight + ( 3*bearing6807_2RS_B) + (16 * bearingStep) - (.5 * bearingStep)])
    rotate([0, 0, 180])
        StepMotor28BYJ();
// arm lower stepper
rotate([0, 180, 0])
    translate([armLength - 8, 0, bearingStep * 2])
        StepMotor28BYJ();
// arm spacers
color([.6, .6, .3])
    armSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
// end arm

// forearm pieces
// lower
color([.1, .7, .1])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
//translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (14 *bearingStep)])
    forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
// upper
color([.2, .8, .2])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
    rotate([180, 0, 0])
        forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
// forearm upper bearing
translate([-armLength, 0, shoulderBaseHeight + (2 * bearing6807_2RS_B) + (7 * bearingStep)])
    %bearing6807_2RS();
// forearm spacers

/*
deprecated
render()
    translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + (2* bearingStep)])
        armJointSpacer(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
*/

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

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

module shoulderSpacers(bearingOD, screwSpacerHeight) {
    union() {
        // screw holes for joining to arm
        rotate([0, 0, -30])
        radial_array_partial(vec = [0, 0, 1], n = 6, 2)
            translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 1.0])
        difference() {
            union () {
                cylinder(h = screwSpacerHeight, r = setScrewRadius * 2);

                }
            cylinder(h = screwTabHeight, r = setScrewRadius);
        }
    }
}

module armSpacers(bearingOD, screwSpacerHeight) {
    union() {
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = 4)
            translate([bearingOD / 2 + (setScrewRadius * 2), 0, shoulderBaseHeight + bearing6807_2RS_B + 2 * bearingStep])
        difference() {
            union () {
                cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius * 2);

                }
            cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius);
        }
        // TODO: put in spacers along arm, make sure holes exist in arm
        translate([- armLength, 0, 0])
        rotate([0, 0, -30])
        radial_array_partial(vec = [0, 0, 1], n = 4, 2)
            translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight + bearing6807_2RS_B + 2 * bearingStep])
        difference() {
            union () {
                cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius * 2);

                }
            cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius);
        }
    }
}

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

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

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

        translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        // lead screw hole
        translate([baseDeckExtension - (leadScrewDiameter * 1.5), 0, 0])
            cylinder(h = shoulderBaseHeight, d = leadScrewDiameter + (leadScrewDiameter / 2));
        // upper to lower spacer screw holes
        rotate([0, 0, -30])
            radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 0])
                    cylinder(h = screwTabHeight, r = setScrewRadius);
           translate([baseDeckExtension / 3, 0, 0])
            rotate([0, 0, -30])
            radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 0])
                    cylinder(h = screwTabHeight, r = setScrewRadius);
    }
    // NOTE: need to add LM8UU mounts
}

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

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

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

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

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

    }
}

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

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

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

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

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

            intersection() {

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

    }
}

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

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

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

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

// global rendering parameters
$fn = 24;

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

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

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

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

// shoulder base
color([.7, .7, 1])
    shoulderBase(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// shoulder lower stepper
rotate([0, 180, 0])
    translate([-8, 0, 10])
        StepMotor28BYJ();
// lower shoulder bearing
translate([0, 0, shoulderBaseHeight + bearingStep])
    %bearing6807_2RS();
// shoulder top
color([.6, .6, .9])
    translate([0, 0, 2 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep)])
    rotate([180, 0, 0])
        shoulderBase(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// upper shoulder bearing
translate([0, 0, shoulderBaseHeight + (3 * bearing6807_2RS_B) + (7 * bearingStep)])
    %bearing6807_2RS();
// shoulder upper stepper
rotate([0, 0, 180])
    translate([-8, 0, 10 + 2 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep)])
        StepMotor28BYJ();
// shoulder spacers
color([.7, .6, .2])
shoulderSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
color([.7, .6, .2])
translate([baseDeckExtension / 3, 0, 0])
shoulderSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
// end shoulder

// lower arm including the shoulder - arm joint
//render()
color([1, .7, .7])
    translate([0, 0, shoulderBaseHeight + bearing6807_2RS_B])
        armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
// upper arm
//render()
color([.9, .7, .7])
    translate([0, 0, shoulderBaseHeight + ( 2*bearing6807_2RS_B) + (12 * bearingStep) - (.5 * bearingStep)])
        rotate([180, 0, 0])
            armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
// elbow joint pieces
// lower bearing
translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + bearingStep])
    %bearing6807_2RS();
// arm upper stepper
translate([-armLength + 8, 0, shoulderBaseHeight + ( 3*bearing6807_2RS_B) + (16 * bearingStep) - (.5 * bearingStep)])
    rotate([0, 0, 180])
        StepMotor28BYJ();
// arm lower stepper
rotate([0, 180, 0])
    translate([armLength - 8, 0, bearingStep * 2])
        StepMotor28BYJ();
// arm spacers
color([.6, .6, .3])
    armSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
// end arm

// forearm pieces
// lower
color([.1, .7, .1])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
//translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (14 *bearingStep)])
    forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
// upper
color([.2, .8, .2])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
    rotate([180, 0, 0])
        forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
// forearm upper bearing
translate([-armLength, 0, shoulderBaseHeight + (2 * bearing6807_2RS_B) + (7 * bearingStep)])
    %bearing6807_2RS();
// forearm spacers

/*
deprecated
render()
    translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + (2* bearingStep)])
        armJointSpacer(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
*/

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

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

module shoulderSpacers(bearingOD, screwSpacerHeight) {
    union() {
        // screw holes for joining to arm
        rotate([0, 0, -30])
        radial_array_partial(vec = [0, 0, 1], n = 6, 2)
            translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 1.0])
        difference() {
            union () {
                cylinder(h = screwSpacerHeight, r = setScrewRadius * 2);

                }
            cylinder(h = screwTabHeight, r = setScrewRadius);
        }
    }
}

module armSpacers(bearingOD, screwSpacerHeight) {
    union() {
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = 4)
            translate([bearingOD / 2 + (setScrewRadius * 2), 0, shoulderBaseHeight + bearing6807_2RS_B + 2 * bearingStep])
        difference() {
            union () {
                cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius * 2);

                }
            cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius);
        }
        // TODO: put in spacers along arm, make sure holes exist in arm
        translate([- armLength, 0, 0])
        rotate([0, 0, -30])
        radial_array_partial(vec = [0, 0, 1], n = 4, 2)
            translate([bearingOD / 2 + (setScrewRadius * 2), 0, shoulderBaseHeight + bearing6807_2RS_B + 2 * bearingStep])
        difference() {
            union () {
                cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius * 2);

                }
            cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius);
        }
    }
}

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

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

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

        translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        // lead screw hole
        translate([baseDeckExtension - (leadScrewDiameter * 1.5), 0, 0])
            cylinder(h = shoulderBaseHeight, d = leadScrewDiameter + (leadScrewDiameter / 2));
        // upper to lower spacer screw holes
        rotate([0, 0, -30])
            radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 0])
                    cylinder(h = screwTabHeight, r = setScrewRadius);
           translate([baseDeckExtension / 3, 0, 0])
            rotate([0, 0, -30])
            radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 0])
                    cylinder(h = screwTabHeight, r = setScrewRadius);
    }
    // NOTE: need to add LM8UU mounts
}

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

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

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

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

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

    }
}

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

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

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

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

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

            intersection() {

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

    }
}

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

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

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


orientation du trou de vis vers le méplat.


Round slots for easier cnc routing

Round slots for easier cnc routing

box_center = [120,160];
box_size = [192,188];
box_front_size = [100,188];

// Non-square pattern intentional; avoid colliding with pi bracket and reduce
// number of possible wrong orientations by half.
box_hole_pattern = [
  [70, 60],
  [70, -60],
  [-70, 60],
  [-70, -60],
];

box_hole_locations=[
  for (p = box_hole_pattern) box_center + p
];

frame_hole_locations=[
  [20,7.5],
  [62,292.5],
];

plate_width=235;
plate_height=300;

arcade_button_hole_size=24;
arcade_button_pos = [18+27,15+42];
badge_reader_hole_size=17;

module Plate(cap_size) {
  difference() {
    square([plate_width, plate_height]);
    translate([0,plate_height-30]) rotate(atan2(30, 40)) square([100,100]);
    for(p = box_hole_locations)
      translate(p) circle(d=cap_size);
    for(p = frame_hole_locations)
      translate(p) circle(d=4.5);
  }
}

module Main() {
  Plate(cap_size=25,$fn=128);
  translate([plate_width+4,0])
    Plate(cap_size=4.2,$fn=128);
}

module CapHead(d,h) {
  color([0.8,0.5,0.5]) {
    translate([0,0,-h]) cylinder(d=d,h=h);
    cylinder(d=d*1.5,h=d);
  }
}

module Leader(h) {
  color([0.5,0.5,0.5,0.3]) cylinder(d=1,h=h);
}

module GhostBox(dims) {
  color([0.5,0.5,0.5,0.3]) cube(dims);
}

module Exploded() {
  linear_extrude(height=6) Inner();
  translate([0,0,80]) linear_extrude(height=6) Outer();
  for(p = box_hole_locations) {
    translate(p) {
      translate([0,0,-60]) scale([1,1,-1]) CapHead(4,20,$fn=32);
      translate([0,0,-40]) Leader(160);
    }
  }
  for(p = frame_hole_locations) {
    translate(p) {
      translate([0,0,130]) CapHead(4,20,$fn=32);
      translate([0,0,-20]) Leader(130);
    }
  }
  translate([box_center[0],box_center[1],120]) translate([-100,-100]) GhostBox([box_size[0],box_size[1],90]);
}

module Slot(d, dist) {
  hull() for(y=[dist/2,-dist/2]) translate([0,y]) circle(d=d);
}

module ZiptieMount() {
  for(x=[200,210]) translate([x,30]) Slot(3, 7, $fn=16);
}

module Inner() {
  difference() {
    Plate(cap_size=25,$fn=128);
    hull() ZiptieMount();
  }
}

module Outer() {
  difference() {
    Plate(cap_size=4.2,$fn=128);
    ZiptieMount();
  }
}

module HoleTemplate() {
  $fn=32;
  difference() {
    square(box_size, center=true);
    for(p = box_hole_pattern) {
      translate(p) circle(d=3);
    }
    translate([-90,0]) text("A", halign="left", size=5);
    translate([90,0]) text("B", halign="right", size=5);
    translate([0,60]) text("4x 4.2mm", halign="center", size=5);
    translate([80,40]) text("Front ->", halign="right", size=5);
    translate([-80,40]) text("<- Back", halign="left", size=5);
    translate([0,10]) text("(place on back of box)", halign="center", size=8);
    translate([0,-10]) text("(verify interior 5 holes at sides)", halign="center", size=8);
  }
}

module CrosshairCircle(d) {
  difference() {
    circle(d=d);
    square([1,d*0.7], center=true);
    square([d*0.7, 1], center=true);
  }
}

module LidHoleTemplate() {
  $fn=32;
  difference() {
    square(box_size, center=true);
    translate([-box_size[0]/2+3,0]) text("C", halign="left", size=5);
    translate([box_size[0]/2-3,0]) text("D", halign="right", size=5);
    for(y_scale=[1,-1])
      scale([1,y_scale])
        translate([-box_size[0]/2+arcade_button_pos[0],
                   -box_size[1]/2+arcade_button_pos[1]])
          CrosshairCircle(arcade_button_hole_size);
  }
}

module FrontHoleTemplate() {
  $fn=32;
  difference() {
    square(box_front_size, center=true);
    translate([box_front_size[0]/2-20, 0]) square([1,box_front_size[1]-2], center=true);
    text("Front", halign="center", size=5);
    translate([-box_front_size[0]/2+3,0]) text("B", halign="left", size=5);
    translate([box_front_size[0]/2-3,0]) text("C", halign="right", size=5);
    translate([0,60]) CrosshairCircle(badge_reader_hole_size);
  }
}

module BackHoleTemplate() {
  $fn=32;
  difference() {
    square(box_front_size, center=true);
    translate([-box_front_size[0]/2+20, 0]) square([1,box_front_size[1]-2], center=true);
    text("Back", halign="center", size=5);
    translate([box_front_size[0]/2-3,0]) text("A", halign="right", size=5);
    translate([-box_front_size[0]/2+3,0]) text("D", halign="left", size=5);
    translate([box_front_size[0]/2-35,box_front_size[1]/2-35])
      CrosshairCircle(8);  // power
    translate([box_front_size[0]/2-50,box_front_size[1]/2-35])
      CrosshairCircle(8);  // actuator cables
    translate([box_front_size[0]/2-80+4,box_front_size[1]/2-35])
      CrosshairCircle(8);  // actuator cables
  }
}

box_center = [120,160];
box_size = [192,188];
box_front_size = [100,188];

// Non-square pattern intentional; avoid colliding with pi bracket and reduce
// number of possible wrong orientations by half.
box_hole_pattern = [
  [70, 60],
  [70, -60],
  [-70, 60],
  [-70, -60],
];

box_hole_locations=[
  for (p = box_hole_pattern) box_center + p
];

frame_hole_locations=[
  [20,7.5],
  [62,292.5],
];

plate_width=235;
plate_height=300;

arcade_button_hole_size=24;
arcade_button_pos = [18+27,15+42];
badge_reader_hole_size=17;

module Plate(cap_size) {
  difference() {
    square([plate_width, plate_height]);
    translate([0,plate_height-30]) rotate(atan2(30, 40)) square([100,100]);
    for(p = box_hole_locations)
      translate(p) circle(d=cap_size);
    for(p = frame_hole_locations)
      translate(p) circle(d=4.5);
  }
}

module Main() {
  Plate(cap_size=25,$fn=128);
  translate([plate_width+4,0])
    Plate(cap_size=4.2,$fn=128);
}

module CapHead(d,h) {
  color([0.8,0.5,0.5]) {
    translate([0,0,-h]) cylinder(d=d,h=h);
    cylinder(d=d*1.5,h=d);
  }
}

module Leader(h) {
  color([0.5,0.5,0.5,0.3]) cylinder(d=1,h=h);
}

module GhostBox(dims) {
  color([0.5,0.5,0.5,0.3]) cube(dims);
}

module Exploded() {
  linear_extrude(height=6) Inner();
  translate([0,0,80]) linear_extrude(height=6) Outer();
  for(p = box_hole_locations) {
    translate(p) {
      translate([0,0,-60]) scale([1,1,-1]) CapHead(4,20,$fn=32);
      translate([0,0,-40]) Leader(160);
    }
  }
  for(p = frame_hole_locations) {
    translate(p) {
      translate([0,0,130]) CapHead(4,20,$fn=32);
      translate([0,0,-20]) Leader(130);
    }
  }
  translate([box_center[0],box_center[1],120]) translate([-100,-100]) GhostBox([box_size[0],box_size[1],90]);
}

module ZiptieMount() {
  for(x=[200,210]) translate([x,30]) square([3,6.5], center=true);
}

module Inner() {
  difference() {
    Plate(cap_size=25,$fn=128);
    hull() ZiptieMount();
  }
}

module Outer() {
  difference() {
    Plate(cap_size=4.2,$fn=128);
    ZiptieMount();
  }
}

module HoleTemplate() {
  $fn=32;
  difference() {
    square(box_size, center=true);
    for(p = box_hole_pattern) {
      translate(p) circle(d=3);
    }
    translate([-90,0]) text("A", halign="left", size=5);
    translate([90,0]) text("B", halign="right", size=5);
    translate([0,60]) text("4x 4.2mm", halign="center", size=5);
    translate([80,40]) text("Front ->", halign="right", size=5);
    translate([-80,40]) text("<- Back", halign="left", size=5);
    translate([0,10]) text("(place on back of box)", halign="center", size=8);
    translate([0,-10]) text("(verify interior 5 holes at sides)", halign="center", size=8);
  }
}

module CrosshairCircle(d) {
  difference() {
    circle(d=d);
    square([1,d*0.7], center=true);
    square([d*0.7, 1], center=true);
  }
}

module LidHoleTemplate() {
  $fn=32;
  difference() {
    square(box_size, center=true);
    translate([-box_size[0]/2+3,0]) text("C", halign="left", size=5);
    translate([box_size[0]/2-3,0]) text("D", halign="right", size=5);
    for(y_scale=[1,-1])
      scale([1,y_scale])
        translate([-box_size[0]/2+arcade_button_pos[0],
                   -box_size[1]/2+arcade_button_pos[1]])
          CrosshairCircle(arcade_button_hole_size);
  }
}

module FrontHoleTemplate() {
  $fn=32;
  difference() {
    square(box_front_size, center=true);
    translate([box_front_size[0]/2-20, 0]) square([1,box_front_size[1]-2], center=true);
    text("Front", halign="center", size=5);
    translate([-box_front_size[0]/2+3,0]) text("B", halign="left", size=5);
    translate([box_front_size[0]/2-3,0]) text("C", halign="right", size=5);
    translate([0,60]) CrosshairCircle(badge_reader_hole_size);
  }
}

module BackHoleTemplate() {
  $fn=32;
  difference() {
    square(box_front_size, center=true);
    translate([-box_front_size[0]/2+20, 0]) square([1,box_front_size[1]-2], center=true);
    text("Back", halign="center", size=5);
    translate([box_front_size[0]/2-3,0]) text("A", halign="right", size=5);
    translate([-box_front_size[0]/2+3,0]) text("D", halign="left", size=5);
    translate([box_front_size[0]/2-35,box_front_size[1]/2-35])
      CrosshairCircle(8);  // power
    translate([box_front_size[0]/2-50,box_front_size[1]/2-35])
      CrosshairCircle(8);  // actuator cables
    translate([box_front_size[0]/2-80+4,box_front_size[1]/2-35])
      CrosshairCircle(8);  // actuator cables
  }
}


fixed projector distance

fixed projector distance

use <projector_plate.scad>;
include <projector.scad>;
use <plate.scad>;
include <profile.scad>;
use <../scad/ob_wheel.scad>
use <../scad/ob_spacer.scad>
include <gantry_cart.scad>
use <../scad/brackets.scad>
use <../scad/geom.scad>
use <support_projector_beam.scad>
include <materials.scad>
use <basin_support.scad>
use <big_screw.scad>

module printer(projector_position = 0) {
  offset_depth = 50;

  middle_sections = 2;

  height = 500;
  width = 560;
  base_depth = 440;
  display_projection = true;
  base_sections = 3;

  projector_movement = height / 2 - acer_projector_distances[projector_position] + 20;

  // projector
  translate([0, 0, -offset_depth]) {
    translate([0, projector_movement, 0]) {
      center_projector() {
        Acer_Plate(160, 120, 85, 100);
        Acer_H6510BD(display_projection);
      }
    }
  }
  beam_offset = 10;
  beam_width = width - 2 * beam_offset;

  carriage_tower_sections = 3;

  translate([0, projector_movement, -offset_depth]) {
    translate([-beam_width/2,-20 * base_sections,-10])
      rotate([90,90,90])
        profile(base_sections, beam_width);
  /*
    translate([beam_width/2,-60,-10])
      rotate([90,0,90])
        gantry_cart_big(carriage_tower_sections, offset = 1);
    translate([-beam_width/2,-60,-10])
      rotate([90,0,-90])
        gantry_cart_big(carriage_tower_sections, offset = 1);
  */
  }

  // projector towers
  translate([0, 0, -offset_depth]) {
    translate([-width/2,-height/2,-10])
      rotate([-90,0,0])
        profile(carriage_tower_sections, height);
    translate([width/2,-height/2,-10])
      rotate([-90,0,0])
        profile(carriage_tower_sections, height);
  }

  // supports for horizontal beam
  translate([0, 20, -offset_depth])
  for(d = acer_projector_distances) {
    translate([0,d-height/2+10,0])
      support_projector_beam(width-60);
  }
  //height / 2 - d

  // base
  module base(width, depth, sections = 2) {
    translate([-width/2,0,-base_depth/2])
      rotate([0,0,0])
        profile(sections, base_depth);

    translate([width/2,0,-base_depth/2])
      rotate([0,0,0])
        profile(sections, base_depth);

    lateral_beam_width = width - 20;
    translate([-lateral_beam_width/2,0,-base_depth/2+10])
      rotate([0,90,0])
        profile(sections, lateral_beam_width);

    translate([-lateral_beam_width/2,0,base_depth/2-10])
      rotate([0,90,0])
        profile(sections, lateral_beam_width);
  }

  module baser(width, depth, sections = 2) {
    translate([(- width + sections * 20) / 2 - 10, -10, -base_depth/2])
      rotate([0,0,90])
        profile(sections, base_depth);

    translate([(  width - sections * 20) / 2 + 10, -10, -base_depth/2])
      rotate([0,0,90])
        profile(sections, base_depth);

    lateral_beam_width = width - 30 * sections;
    translate([-lateral_beam_width/2, -10, -base_depth/2+20])
      rotate([90,0,90])
        profile(sections, lateral_beam_width);
    translate([-lateral_beam_width/2, -10, base_depth/2-20])
      rotate([90,0,90])
        profile(sections, lateral_beam_width);
  }

  bottom_sections = 2;
  translate([0,-(height+bottom_sections*20)/2,0])
    base(width, base_depth, bottom_sections);

  translate([0,(height+middle_sections*20)/2,0])
    baser(width, base_depth, 2);

  // support towers
  tower_pos = base_depth / 2 - 10;
  translate([-width/2,-height/2,tower_pos])
    rotate([-90,0,0])
      profile(1, height);
  translate([width/2,-height/2,tower_pos])
    rotate([-90,0,0])
      profile(1, height);

  rotate([0,180,0]) {

    offset = 16;
    plate_width = width - 20 - offset * 2;
    plate_depth = base_depth - 60 * 2;
    cut_width = 440;
    cut_offset = 7.5;
    translate([
      -plate_width/2,
      height/2 + 20,
      -plate_depth / 2 + 20 - offset])
      basin_support(plate_width, plate_depth, cut_width, cut_offset);

    translate([0, height/2 + 20 * middle_sections, base_depth / 2 + 20])
      big_screw();

    // TODO review
    screw_height = 640;
    rail_sections = 2;
    rotate([-90, 0, 0]) {
      translate([65, -base_depth / 2 - 20, -height / 2 - 20 * (bottom_sections)]) {
        profile(rail_sections, screw_height + height + 20 * (bottom_sections + middle_sections));
      }
      translate([-65, -base_depth / 2 - 20, -height / 2 - 20 * (bottom_sections)]) {
        profile(rail_sections, screw_height + height + 20 * (bottom_sections + middle_sections));
      }
    }
    translate([0,0,30]) {
      translate([40, height / 2 + 20 * middle_sections + 260, base_depth / 2 + 20])
        rotate([0, 180, 0])
          profile(4, width / 2 + rail_sections * 2 - 5);
      translate([-40, height / 2 + 20 * middle_sections + 260, base_depth / 2 + 20])
        rotate([0, 180, 0])
          profile(4, width / 2 + rail_sections * 2 - 5);
      translate([-50, height / 2 + 20 * middle_sections + 300, base_depth / 2 -60])
        plate(100, 4, 80);
      translate([-50, height / 2 + 20 * middle_sections + 216, base_depth / 2 -60])
        plate(100, 4, 80);
      translate([0, height / 2 + 20 * middle_sections + 300, base_depth / 2 - width / 2 + 30])
        rotate([90,90,0])
          profile(3, 120);

      translate([65, height / 2 + 20 * middle_sections + 300 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([65, height / 2 + 20 * middle_sections + 240 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([65, height / 2 + 20 * middle_sections + 270 - 10, base_depth / 2 + rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();

      translate([-65, height / 2 + 20 * middle_sections + 300 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([-65, height / 2 + 20 * middle_sections + 240 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([-65, height / 2 + 20 * middle_sections + 270 - 10, base_depth / 2 + rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
    }
  }
}

use <projector_plate.scad>;
include <projector.scad>;
use <plate.scad>;
include <profile.scad>;
use <../scad/ob_wheel.scad>
use <../scad/ob_spacer.scad>
include <gantry_cart.scad>
use <../scad/brackets.scad>
use <../scad/geom.scad>
use <support_projector_beam.scad>
include <materials.scad>
use <basin_support.scad>
use <big_screw.scad>

module printer(projector_position = 0) {
  offset_depth = 50;

  middle_sections = 2;

  height = 500;
  width = 560;
  base_depth = 440;
  display_projection = false;
  base_sections = 3;

  projector_movement = height / 2 - acer_projector_distances[projector_position] + middle_sections * 20;

  // projector
  translate([0, 0, -offset_depth]) {
    translate([0, projector_movement, 0]) {
      center_projector() {
        Acer_Plate(160, 120, 85, 100);
        Acer_H6510BD(display_projection);
      }
    }
  }
  beam_offset = 10;
  beam_width = width - 2 * beam_offset;

  carriage_tower_sections = 3;

  translate([0, projector_movement, -offset_depth]) {
    translate([-beam_width/2,-20 * base_sections,-10])
      rotate([90,90,90])
        profile(base_sections, beam_width);
  /*
    translate([beam_width/2,-60,-10])
      rotate([90,0,90])
        gantry_cart_big(carriage_tower_sections, offset = 1);
    translate([-beam_width/2,-60,-10])
      rotate([90,0,-90])
        gantry_cart_big(carriage_tower_sections, offset = 1);
  */
  }

  // projector towers
  translate([0, 0, -offset_depth]) {
    translate([-width/2,-height/2,-10])
      rotate([-90,0,0])
        profile(carriage_tower_sections, height);
    translate([width/2,-height/2,-10])
      rotate([-90,0,0])
        profile(carriage_tower_sections, height);
  }

  // supports for horizontal beam
  translate([0, middle_sections * 20, -offset_depth])
  for(d = acer_projector_distances) {
    translate([0,d-height/2+10,0])
      support_projector_beam(width-60);
  }
  //height / 2 - d

  // base
  module base(width, depth, sections = 2) {
    translate([-width/2,0,-base_depth/2])
      rotate([0,0,0])
        profile(sections, base_depth);

    translate([width/2,0,-base_depth/2])
      rotate([0,0,0])
        profile(sections, base_depth);

    lateral_beam_width = width - 20;
    translate([-lateral_beam_width/2,0,-base_depth/2+10])
      rotate([0,90,0])
        profile(sections, lateral_beam_width);

    translate([-lateral_beam_width/2,0,base_depth/2-10])
      rotate([0,90,0])
        profile(sections, lateral_beam_width);
  }

  module baser(width, depth, sections = 2) {
    translate([(- width + sections * 20) / 2 - 10, -10, -base_depth/2])
      rotate([0,0,90])
        profile(sections, base_depth);

    translate([(  width - sections * 20) / 2 + 10, -10, -base_depth/2])
      rotate([0,0,90])
        profile(sections, base_depth);

    lateral_beam_width = width - 30 * sections;
    translate([-lateral_beam_width/2, -10, -base_depth/2+20])
      rotate([90,0,90])
        profile(sections, lateral_beam_width);
    translate([-lateral_beam_width/2, -10, base_depth/2-20])
      rotate([90,0,90])
        profile(sections, lateral_beam_width);
  }

  bottom_sections = 2;
  translate([0,-(height+bottom_sections*20)/2,0])
    base(width, base_depth, bottom_sections);

  translate([0,(height+middle_sections*20)/2,0])
    baser(width, base_depth, 2);

  // support towers
  tower_pos = base_depth / 2 - 10;
  translate([-width/2,-height/2,tower_pos])
    rotate([-90,0,0])
      profile(1, height);
  translate([width/2,-height/2,tower_pos])
    rotate([-90,0,0])
      profile(1, height);

  rotate([0,180,0]) {

    offset = 16;
    plate_width = width - 20 - offset * 2;
    plate_depth = base_depth - 60 * 2;
    cut_width = 440;
    cut_offset = 7.5;
    translate([
      -plate_width/2,
      height/2 + 20,
      -plate_depth / 2 + 20 - offset])
      basin_support(plate_width, plate_depth, cut_width, cut_offset);

    translate([0, height/2 + 20 * middle_sections, base_depth / 2 + 20])
      big_screw();

    // TODO review
    screw_height = 640;
    rail_sections = 2;
    rotate([-90, 0, 0]) {
      translate([65, -base_depth / 2 - 20, -height / 2 - 20 * (bottom_sections)]) {
        profile(rail_sections, screw_height + height + 20 * (bottom_sections + middle_sections));
      }
      translate([-65, -base_depth / 2 - 20, -height / 2 - 20 * (bottom_sections)]) {
        profile(rail_sections, screw_height + height + 20 * (bottom_sections + middle_sections));
      }
    }
    translate([0,0,30]) {
      translate([40, height / 2 + 20 * middle_sections + 260, base_depth / 2 + 20])
        rotate([0, 180, 0])
          profile(4, width / 2 + rail_sections * 2 - 5);
      translate([-40, height / 2 + 20 * middle_sections + 260, base_depth / 2 + 20])
        rotate([0, 180, 0])
          profile(4, width / 2 + rail_sections * 2 - 5);
      translate([-50, height / 2 + 20 * middle_sections + 300, base_depth / 2 -60])
        plate(100, 4, 80);
      translate([-50, height / 2 + 20 * middle_sections + 216, base_depth / 2 -60])
        plate(100, 4, 80);
      translate([0, height / 2 + 20 * middle_sections + 300, base_depth / 2 - width / 2 + 30])
        rotate([90,90,0])
          profile(3, 120);

      translate([65, height / 2 + 20 * middle_sections + 300 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([65, height / 2 + 20 * middle_sections + 240 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([65, height / 2 + 20 * middle_sections + 270 - 10, base_depth / 2 + rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();

      translate([-65, height / 2 + 20 * middle_sections + 300 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([-65, height / 2 + 20 * middle_sections + 240 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([-65, height / 2 + 20 * middle_sections + 270 - 10, base_depth / 2 + rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
    }
  }
}