[3d] Update Pi connector offsets deeper in case, wider LCD hole

include <fillet.scad>

// Pit probe type
Control_Probe = "Thermocouple"; // [Thermocouple,Thermistor]
// Raspberry Pi Model
Pi_Model = "3B/2B/1B+"; // [3B/2B/1B+,1A+,Zero]
// Which case halves
Pieces = "Both"; // [Both,Top,Bottom]

/* [Hidden] */
function inch(x) = x*25.4;

w = inch(3.75)+0.5; // overall interior case width
d = inch(3.75)-0.5; // overall interior case depth
h_b = 32; // overall interior case height

probe_centerline = 9.0; // case is split along probe centerline

pic_ex = 2;
lcd_mount_t = 7;

wall = 2.1*1.41; // thickness of side walls
wall_t = 2; // thickness of top and bottom walls
e = 0.01;

module jhole(d, h) {
  translate([0,0,h/2]) cube([2*(wall+pic_ex),d,h], center=true);
}

module phole() {
  // Hole for thermistor probe jack
  rotate([0,90,0]) cylinder(2*wall, d=4.5, $fn=16);
}

module screwhole() {
  // Screw hole for bottom of case (including nut)
  //translate([0,0,-e]) cylinder(h_b+wall_t, d=3.4, $fn=18);
  translate([0,0,-e]) {
    cylinder(0.4, d1=7.4, d2=6.6, $fn=6);
    translate([0,0,0.4]) cylinder(3, d=6.6, $fn=6);
  }
  translate([0,0,3+0.2]) cylinder(h_b+2*wall_t, d=3.4, $fn=18);
  translate([0,0,h_b+wall_t]) cylinder(3, d=5.5, $fn=18);
}

module screwhole2() {
  translate([0,0,-e]) cylinder(3, d=6, $fn=18);
  translate([0,0,3+0.4]) cylinder(h_b-3-0.4, d=3.4, $fn=18);
}

module pic_ex_cube() {
  translate([0,33.75,2])
    cube_fillet([pic_ex+e, 59.5, 20.8],
      vertical=[0, pic_ex, pic_ex, 0],
      top=[0,pic_ex,0,0],
      bottom=[0,pic_ex,0,0]);
}

module screw_pimount() {
  // 2mm height is good for screw holes
  difference() {
    cylinder(h=2.25, d=6.4, $fn=18);
    //cylinder(h=2+e, d=2.5, $fn=16);
  }
}

module btn_rnd(dia=10) {
  cylinder(wall_t+2*e, d1=dia, d2=dia+1.5*wall_t, $fn=24);
  translate([-6.25,-6.25,0]) cube([12.5,12.5,0.75+e]);
}

module btn_square(sq=13) {
  translate([-sq/2,-sq/2,0]) cube([sq,sq,wall_t+2*e]);
}

module tc_plusminus() {
  T=0.75+e;
  H=2;
  W=6;
  // Minus
  translate([0,2,0])
    cube_fillet([T, W, H], top=[0,0,0,T]);
  translate([0,-(2+W),0]) {
    cube_fillet([T, W, H], top=[0,0,0,T]);
    translate([0,(W-H)/2,(H-W)/2])
      cube_fillet([T, H, W], top=[0,0,0,T]);
  }
}

module led_hole() {
  cylinder(wall_t+2*e, d=3.4, $fn=16);
}

module nuttrap() {
  ww_w=3;
  ww_d=2;
  nut_h=2.8;
  nut_ingress = 5.8; //nut_d * sin(60);
  nut_d = nut_ingress / sin(60);
  oa_h=wall_t+0.4+nut_h+wall_t+6.7;

  // bottom half for M3 socket cap screw (flush)
  difference() {
    translate([-5.5/2-ww_w,-3.4/2-ww_d,0])
      cube_fillet([5.5+2*ww_w,3.4+2.5*ww_d,6], vertical=[3.4,3.4], $fn=20);
    // socket cap
    translate([0,0,-e]) cylinder(3.5, d=6, $fn=18);
    // screw shaft
    translate([0,0,3.5+0.3]) cylinder(oa_h-3, d=3.4, $fn=18);
  }

  // top half M3 nut trap
  translate([0,0,h_b+wall_t-oa_h])
  difference() {
    translate([-(nut_d/2+ww_w), -(nut_d/2+ww_d), 0])
      cube_fillet([nut_d+2*ww_w,nut_d+2*ww_d,oa_h],
        vertical=[3.4,3.4], $fn=20);
    // M3 screw
    translate([0,0,-e]) cylinder(wall_t, d1=4, d2=3.4, $fn=16);
    // nut hole / M3 extra
    translate([0,0,wall_t+0.3]) {
      translate([-0.4,0,0]) // nut offset slightly deeper for easier alignment
        cylinder(nut_h*1.5+e, d=nut_d, $fn=6);  // nut
      cylinder(oa_h-wall_t-0.3, d=4, $fn=16);  // M3 with plenty of clearance
    }
    // nut ingress
    translate([0,-nut_ingress/2,wall_t+0.3])
      cube([nut_d/2+ww_w+e,nut_ingress,nut_h+e]);
  }
}

module locklip_p(l, l_offset=1,
  lip_insert_depth=2.0, // how deep V to insert
  lip_v_off=0.3, // extra height before starting insert
  lip_h_off=0.4, // back connector away from mating area
  lip_w=1.5  // thickness of attachment beam
  ) {
  translate([l_offset,0,0]) rotate([90,0,0]) rotate([0,90,0])
    linear_extrude(height=l-2*l_offset) polygon(points=[
      [0, -lip_w-lip_insert_depth-lip_h_off],
      [0, 0],
      [-lip_insert_depth-lip_h_off, 0],
      [-lip_insert_depth-lip_h_off, lip_v_off],
      [-lip_h_off, lip_v_off+lip_insert_depth],
      [-lip_insert_depth-lip_h_off, lip_v_off+2*lip_insert_depth,],
      [-lip_w-lip_insert_depth-lip_h_off, lip_v_off+2*lip_insert_depth],
      [-lip_w-lip_insert_depth-lip_h_off, 0]
    ]);
}

module locklip_n(l, l_offset=1,
  lip_insert_depth=2.2, // how deep V to insert
  lip_tip_clip=0.3, // how much to shave off the top tip
  ) {
  translate([l-l_offset,0,0]) rotate([90,0,0]) rotate([0,-90,0])
    linear_extrude(height=l-2*l_offset) polygon(points=[
      [0.1, -3*lip_insert_depth],  // 0.1 to add depth to keep extrusion manifold
      [0.1, 0],
      [-lip_insert_depth+lip_tip_clip, 0],
      [-lip_insert_depth+lip_tip_clip, -lip_tip_clip],
      [-e, -lip_insert_depth],
      [-lip_insert_depth, -2*lip_insert_depth]
    ]);
}

module lcd_screw() {
  rotate([180]) difference() {
    //cylinder(lcd_mount_t, d=2.5+3.2, $fn=16);
    cylinder(lcd_mount_t+e, d=2.5, $fn=16);
  }
}

module lcd_mount() {
  // Assuming starting at bottom left screw hole
  lcd_screw();
  //translate([75,0,0]) lcd_screw(); // bottom right hole obscured by PCB
  translate([0,31,0]) lcd_screw();
  translate([75,31,0]) lcd_screw();
}

module lcd_neg() {
  // Assuming starting at bottom left screw hole
  translate([1.0, 2.1, 0])
    cube([73.0, 26.3, lcd_mount_t+wall_t-0.8]); // black bezel inset
  translate([5.5, 7.8, 0])
    cube([64.0, 15.4, lcd_mount_t+wall_t+2*e]); // LCD active area
  translate([4.23, -2.5, 0])
    cube([16*2.54, 5, lcd_mount_t+wall_t-0.8]); // pins cutout
}

module hm43() {
difference() {
  union() {
    cube_fillet([w+2*wall, d+2*wall, h_b+2*wall_t],
      vertical=[wall/2,wall/2,wall/2,wall/2],
      top=[wall,wall,wall_t,wall],
      bottom=[wall/2,wall/2,wall/2,wall/2], $fn=4);
    // extra thick by Pi connectors
    if (Pi_Model != "Zero")
      translate([-pic_ex,wall,wall_t])
        pic_ex_cube();
    // TC +/-
    if (Control_Probe == "Thermocouple")
      translate([w+wall*2-e,wall+10,wall_t+18]) tc_plusminus();
  }
  translate([wall, wall, wall_t]) cube([w, d, h_b+e]);
  if (Pi_Model != "Zero")
    translate([wall-pic_ex+e,wall,wall_t]) pic_ex_cube();

  // Probe jack side
  translate([w+wall*0.5,wall,wall_t]) {
    // Probe jacks
    translate([0,24.25,probe_centerline]) {
      if (Control_Probe == "Thermocouple")
        // TC jack
        translate([0,inch(-0.55)-16.5/2,-1.4]) cube([2*wall, 16.5, 6.5]);
      else
        translate([0,-17.25,0]) phole();
      translate([0,inch(0.37)*0,0]) phole();
      translate([0,inch(0.37)*1,0]) phole();
      translate([0,inch(0.37)*2,0]) phole();
    }
  }
  // Pi connector side
  translate([wall*-0.5,wall,wall_t]) {
    // Pi connectors
    translate([0,0,5]) {
      // ethernet
      if (Pi_Model == "3B/2B/1B+") {
        translate([0,81.5,-1]) jhole(15,13);
        translate([0,81.5,-2]) jhole(5,5);
      }
      // USB 0+1
      if (Pi_Model == "3B/2B/1B+") {
        translate([0,62.75,0]) jhole(13,14.8);
        translate([0,44.75,0]) jhole(13,14.8);
      }
      if (Pi_Model == "1A+")
        translate([0,44.75,0]) jhole(13,7.4);
    }
    // HeaterMeter connectors
    translate([0,0,0]) {
      // Blower/Servo output
      translate([0,25.25,0.2]) jhole(16.7,13);
      // HM power jack
      translate([0,5.25,2.5]) jhole(9.2,11);
    }
  }

  // lcd hole
  translate([wall+10.7, wall+52, h_b+wall_t-lcd_mount_t-e]) lcd_neg();

  // button holes
  translate([wall+48.7, wall+29.4, h_b+wall_t-e]) {
    translate([-inch(1.1)/2,0,0]) btn_rnd(7.2);  // left
    translate([inch(1.1)/2,0,0]) btn_rnd(7.2);   // right
    translate([0,inch(0.9)/2,0]) btn_rnd(7.2);   // up
    translate([0,-inch(0.9)/2,0]) btn_rnd(7.2);  // down
    // LED holes
    translate([inch(1.3), inch(-0.05), 0]) {
      led_hole();  //red
      translate([0, inch(0.35), 0]) led_hole(); //yellow
      translate([0, inch(0.70), 0]) led_hole(); //green
    }
  }
  // close screw holes
  translate([wall+inch(0.8)+1.3,wall+2.9,0]) {
    screwhole2();
    translate([inch(2.0),0,0]) screwhole2();
  }
}  // END OF DIFFERENCE

  // Pi mounting screws
  translate([wall+24,wall+d-7,wall_t]) {
    //screw_pimount();
    translate([58,0,0]) screw_pimount();
    translate([58,-49,0]) screw_pimount();
    translate([0,-49,0]) screw_pimount();
    translate([0,0,0]) screw_pimount();
  }
  // Pi right edge stop
  translate([wall+w-10, wall+d-65, wall_t]) {
    difference() {
      cube_fillet([10,65,3], vertical=[0,0,10/2], $fn=24);
      // Pi B+ microsd gap
      translate([-e,27.5,e]) cube_fillet([3,14,3], vertical=[2,0,0,2], $fn=20);
    }
  }

  // close nut traps
  translate([wall+inch(0.8)+1.3,wall+2.9,0]) {
    nuttrap();
    translate([inch(2.0),0,0]) nuttrap();
  }

  // Top locklip (negative)
  translate([wall, d+wall, probe_centerline+wall_t+e])
    rotate([180]) {
      locklip_n(28);
      translate([w-34,0,0]) locklip_n(34);
    }

  // LCD mount
  difference() {
    union() {
      // Filled block above LCD hole
      translate([wall, wall+d-16, h_b+wall_t-lcd_mount_t]) cube([w,16,lcd_mount_t+e]);
      // LCD grab notch
      translate([wall+10.7, wall+52, h_b+wall_t-lcd_mount_t])
        translate([(77.5-20)/2,33.5-wall_t,-(1.8+wall_t)])
          // 1.8=thickness of LCD pcb
          cube_fillet([20,1.8+wall_t+wall,1.8+wall_t+e], top=[0,0,1.8+wall_t+e],
            vertical=[wall/2,wall/2]);
    }
    translate([wall+10.7, wall+52, h_b+wall_t-lcd_mount_t-e]) lcd_neg();
    translate([wall+10.7, wall+52, h_b+wall_t-e]) lcd_mount();
  }
}

module hm43_split() {
  half=wall_t+probe_centerline;

  // bottom
  if (Pieces != "Top") {
    intersection() {
      hm43();
      translate([-w,-d,0]) cube([w*3, d*3, half]);
    }
    // bottom locklip (postive)
    translate([wall, d+wall, probe_centerline+wall_t]) {
      locklip_p(28);
      translate([w-34,0,0]) locklip_p(34);
    }
  } // if include bottom

  // top
  if (Pieces != "Bottom") {
    translate([0,-2,h_b+2*wall_t]) rotate([180]) intersection() {
      hm43();
      translate([-w,-d,half]) cube([w*3, d*3, h_b]);
    }
  }  // if include top
}

hm43_split();

include <fillet.scad>

// Pit probe type
Control_Probe = "Thermocouple"; // [Thermocouple,Thermistor]
// Raspberry Pi Model
Pi_Model = "3B/2B/1B+"; // [3B/2B/1B+,1A+,Zero]
// Which case halves
Pieces = "Both"; // [Both,Top,Bottom]

/* [Hidden] */
function inch(x) = x*25.4;

w = inch(3.75)+0.5; // overall interior case width
d = inch(3.75)-0.5; // overall interior case depth
h_b = 32; // overall interior case height

probe_centerline = 9.0; // case is split along probe centerline

pic_ex = 2;
lcd_mount_t = 7;

wall = 2.1*1.41; // thickness of side walls
wall_t = 2; // thickness of top and bottom walls
e = 0.01;

module jhole(d, h) {
  translate([0,0,h/2]) cube([2*(wall+pic_ex),d,h], center=true);
}

module phole() {
  // Hole for thermistor probe jack
  rotate([0,90,0]) cylinder(2*wall, d=4.5, $fn=16);
}

module screwhole() {
  // Screw hole for bottom of case (including nut)
  //translate([0,0,-e]) cylinder(h_b+wall_t, d=3.4, $fn=18);
  translate([0,0,-e]) {
    cylinder(0.4, d1=7.4, d2=6.6, $fn=6);
    translate([0,0,0.4]) cylinder(3, d=6.6, $fn=6);
  }
  translate([0,0,3+0.2]) cylinder(h_b+2*wall_t, d=3.4, $fn=18);
  translate([0,0,h_b+wall_t]) cylinder(3, d=5.5, $fn=18);
}

module screwhole2() {
  translate([0,0,-e]) cylinder(3, d=6, $fn=18);
  translate([0,0,3+0.4]) cylinder(h_b-3-0.4, d=3.4, $fn=18);
}

module pic_ex_cube() {
  translate([0,33.75,2])
    cube_fillet([pic_ex+e, 60, 20.8],
      vertical=[0, pic_ex, pic_ex, 0],
      top=[0,pic_ex,0,0],
      bottom=[0,pic_ex,0,0]);
}

module screw_pimount() {
  // 2mm height is good for screw holes
  difference() {
    cylinder(h=2.25, d=6.4, $fn=18);
    //cylinder(h=2+e, d=2.5, $fn=16);
  }
}

module btn_rnd(dia=10) {
  cylinder(wall_t+2*e, d1=dia, d2=dia+1.5*wall_t, $fn=24);
  translate([-6.25,-6.25,0]) cube([12.5,12.5,0.75+e]);
}

module btn_square(sq=13) {
  translate([-sq/2,-sq/2,0]) cube([sq,sq,wall_t+2*e]);
}

module tc_plusminus() {
  T=0.75+e;
  H=2;
  W=6;
  // Minus
  translate([0,2,0])
    cube_fillet([T, W, H], top=[0,0,0,T]);
  translate([0,-(2+W),0]) {
    cube_fillet([T, W, H], top=[0,0,0,T]);
    translate([0,(W-H)/2,(H-W)/2])
      cube_fillet([T, H, W], top=[0,0,0,T]);
  }
}

module led_hole() {
  cylinder(wall_t+2*e, d=3.4, $fn=16);
}

module nuttrap() {
  ww_w=3;
  ww_d=2;
  nut_h=2.8;
  nut_ingress = 5.8; //nut_d * sin(60);
  nut_d = nut_ingress / sin(60);
  oa_h=wall_t+0.4+nut_h+wall_t+6.7;

  // bottom half for M3 socket cap screw (flush)
  difference() {
    translate([-5.5/2-ww_w,-3.4/2-ww_d,0])
      cube_fillet([5.5+2*ww_w,3.4+2.5*ww_d,6], vertical=[3.4,3.4], $fn=20);
    // socket cap
    translate([0,0,-e]) cylinder(3.5, d=6, $fn=18);
    // screw shaft
    translate([0,0,3.5+0.3]) cylinder(oa_h-3, d=3.4, $fn=18);
  }

  // top half M3 nut trap
  translate([0,0,h_b+wall_t-oa_h])
  difference() {
    translate([-(nut_d/2+ww_w), -(nut_d/2+ww_d), 0])
      cube_fillet([nut_d+2*ww_w,nut_d+2*ww_d,oa_h],
        vertical=[3.4,3.4], $fn=20);
    // M3 screw
    translate([0,0,-e]) cylinder(wall_t, d1=4, d2=3.4, $fn=16);
    // nut hole / M3 extra
    translate([0,0,wall_t+0.3]) {
      translate([-0.4,0,0]) // nut offset slightly deeper for easier alignment
        cylinder(nut_h*1.5+e, d=nut_d, $fn=6);  // nut
      cylinder(oa_h-wall_t-0.3, d=4, $fn=16);  // M3 with plenty of clearance
    }
    // nut ingress
    translate([0,-nut_ingress/2,wall_t+0.3])
      cube([nut_d/2+ww_w+e,nut_ingress,nut_h+e]);
  }
}

module locklip_p(l, l_offset=1,
  lip_insert_depth=2.0, // how deep V to insert
  lip_v_off=0.3, // extra height before starting insert
  lip_h_off=0.4, // back connector away from mating area
  lip_w=1.5  // thickness of attachment beam
  ) {
  translate([l_offset,0,0]) rotate([90,0,0]) rotate([0,90,0])
    linear_extrude(height=l-2*l_offset) polygon(points=[
      [0, -lip_w-lip_insert_depth-lip_h_off],
      [0, 0],
      [-lip_insert_depth-lip_h_off, 0],
      [-lip_insert_depth-lip_h_off, lip_v_off],
      [-lip_h_off, lip_v_off+lip_insert_depth],
      [-lip_insert_depth-lip_h_off, lip_v_off+2*lip_insert_depth,],
      [-lip_w-lip_insert_depth-lip_h_off, lip_v_off+2*lip_insert_depth],
      [-lip_w-lip_insert_depth-lip_h_off, 0]
    ]);
}

module locklip_n(l, l_offset=1,
  lip_insert_depth=2.2, // how deep V to insert
  lip_tip_clip=0.3, // how much to shave off the top tip
  ) {
  translate([l-l_offset,0,0]) rotate([90,0,0]) rotate([0,-90,0])
    linear_extrude(height=l-2*l_offset) polygon(points=[
      [0.1, -3*lip_insert_depth],  // 0.1 to add depth to keep extrusion manifold
      [0.1, 0],
      [-lip_insert_depth+lip_tip_clip, 0],
      [-lip_insert_depth+lip_tip_clip, -lip_tip_clip],
      [-e, -lip_insert_depth],
      [-lip_insert_depth, -2*lip_insert_depth]
    ]);
}

module lcd_screw() {
  rotate([180]) difference() {
    //cylinder(lcd_mount_t, d=2.5+3.2, $fn=16);
    cylinder(lcd_mount_t+e, d=2.5, $fn=16);
  }
}

module lcd_mount() {
  // Assuming starting at bottom left screw hole
  lcd_screw();
  //translate([75,0,0]) lcd_screw(); // bottom right hole obscured by PCB
  translate([0,31,0]) lcd_screw();
  translate([75,31,0]) lcd_screw();
}

module lcd_neg() {
  // Assuming starting at bottom left screw hole
  translate([1.50, 2.10, 0])
    cube([73.0, 26.3, lcd_mount_t+wall_t-0.8]); // black bezel inset
  translate([5.75, 7.8, 0])
    cube([63.5, 15.4, lcd_mount_t+wall_t+2*e]); // LCD active area
  translate([4.23, -2.5, 0])
    cube([16*2.54, 5, lcd_mount_t+wall_t-0.8]); // pins cutout
}

module hm43() {
difference() {
  union() {
    cube_fillet([w+2*wall, d+2*wall, h_b+2*wall_t],
      vertical=[wall/2,wall/2,wall/2,wall/2],
      top=[wall,wall,wall_t,wall],
      bottom=[wall/2,wall/2,wall/2,wall/2], $fn=4);
    // extra thick by Pi connectors
    if (Pi_Model != "Zero")
      translate([-pic_ex,wall,wall_t])
        pic_ex_cube();
    // TC +/-
    if (Control_Probe == "Thermocouple")
      translate([w+wall*2-e,wall+10,wall_t+18]) tc_plusminus();
  }
  translate([wall, wall, wall_t]) cube([w, d, h_b+e]);
  if (Pi_Model != "Zero")
    translate([wall-pic_ex+e,wall,wall_t]) pic_ex_cube();

  // Probe jack side
  translate([w+wall*0.5,wall,wall_t]) {
    // Probe jacks
    translate([0,24.25,probe_centerline]) {
      if (Control_Probe == "Thermocouple")
        // TC jack
        translate([0,inch(-0.55)-16.5/2,-1.4]) cube([2*wall, 16.5, 6.5]);
      else
        translate([0,-17.25,0]) phole();
      translate([0,inch(0.37)*0,0]) phole();
      translate([0,inch(0.37)*1,0]) phole();
      translate([0,inch(0.37)*2,0]) phole();
    }
  }
  // Pi connector side
  translate([wall*-0.5,wall,wall_t]) {
    // Pi connectors
    translate([0,0,5]) {
      // ethernet
      if (Pi_Model == "3B/2B/1B+") {
        translate([0,81,-1]) jhole(15,13);
        translate([0,81,-2]) jhole(5,5);
      }
      // USB 0+1
      if (Pi_Model == "3B/2B/1B+") {
        translate([0,62.25,0]) jhole(13,14.8);
        translate([0,44.25,0]) jhole(13,14.8);
      }
      if (Pi_Model == "1A+")
        translate([0,44.25,0]) jhole(13,7.4);
    }
    // HeaterMeter connectors
    translate([0,0,0]) {
      // Blower/Servo output
      translate([0,25.25,0.2]) jhole(16.7,13);
      // HM power jack
      translate([0,5.25,2.5]) jhole(9.2,11);
    }
  }

  // lcd hole
  translate([wall+10.7, wall+52, h_b+wall_t-lcd_mount_t-e]) lcd_neg();

  // button holes
  translate([wall+48.7, wall+29.4, h_b+wall_t-e]) {
    translate([-inch(1.1)/2,0,0]) btn_rnd(7.2);  // left
    translate([inch(1.1)/2,0,0]) btn_rnd(7.2);   // right
    translate([0,inch(0.9)/2,0]) btn_rnd(7.2);   // up
    translate([0,-inch(0.9)/2,0]) btn_rnd(7.2);  // down
    // LED holes
    translate([inch(1.3), inch(-0.05), 0]) {
      led_hole();  //red
      translate([0, inch(0.35), 0]) led_hole(); //yellow
      translate([0, inch(0.70), 0]) led_hole(); //green
    }
  }
  // close screw holes
  translate([wall+inch(0.8)+1.3,wall+2.9,0]) {
    screwhole2();
    translate([inch(2.0),0,0]) screwhole2();
  }
}  // END OF DIFFERENCE

  // Pi mounting screws
  translate([wall+24,wall+d-7,wall_t]) {
    //screw_pimount();
    translate([58,0,0]) screw_pimount();
    translate([58,-49,0]) screw_pimount();
    translate([0,-49,0]) screw_pimount();
    translate([0,0,0]) screw_pimount();
  }
  // Pi right edge stop
  translate([wall+w-10, wall+d-65, wall_t]) {
    difference() {
      cube_fillet([10,65,3], vertical=[0,0,10/2], $fn=24);
      // Pi B+ microsd gap
      translate([-e,27.5,e]) cube_fillet([3,14,3], vertical=[2,0,0,2], $fn=20);
    }
  }

  // close nut traps
  translate([wall+inch(0.8)+1.3,wall+2.9,0]) {
    nuttrap();
    translate([inch(2.0),0,0]) nuttrap();
  }

  // Top locklip (negative)
  translate([wall, d+wall, probe_centerline+wall_t+e])
    rotate([180]) {
      locklip_n(27);
      translate([w-33,0,0]) locklip_n(33);
    }

  // LCD mount
  difference() {
    union() {
      // Filled block above LCD hole
      translate([wall, wall+d-16, h_b+wall_t-lcd_mount_t]) cube([w,16,lcd_mount_t+e]);
      // LCD grab notch
      translate([wall+10.7, wall+52, h_b+wall_t-lcd_mount_t])
        translate([(77.5-20)/2,33.5-wall_t,-(1.8+wall_t)])
          // 1.8=thickness of LCD pcb
          cube_fillet([20,1.8+wall_t+wall,1.8+wall_t+e], top=[0,0,1.8+wall_t+e],
            vertical=[wall/2,wall/2]);
    }
    translate([wall+10.7, wall+52, h_b+wall_t-lcd_mount_t-e]) lcd_neg();
    translate([wall+10.7, wall+52, h_b+wall_t-e]) lcd_mount();
  }
}

module hm43_split() {
  half=wall_t+probe_centerline;

  // bottom
  if (Pieces != "Top") {
    intersection() {
      hm43();
      translate([-w,-d,0]) cube([w*3, d*3, half]);
    }
    // bottom locklip (postive)
    translate([wall, d+wall, probe_centerline+wall_t]) {
      locklip_p(27);
      translate([w-33,0,0]) locklip_p(33);
    }
  } // if include bottom

  // top
  if (Pieces != "Bottom") {
    translate([0,-2,h_b+2*wall_t]) rotate([180]) intersection() {
      hm43();
      translate([-w,-d,half]) cube([w*3, d*3, h_b]);
    }
  }  // if include top
}

hm43_split();


shapes/rcylinder: wip

shapes/rcylinder: wip

use <misc.scad>
use <transforms.scad>

module cubea(size=[10,10,10], align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cube(size+extrasize, center=true);
        }
    }
}

module rcubea(size=[10,10,10], facets=32, rounding_radius=1, align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            rcube(size=size+extrasize, facets=facets, rounding_radius=rounding_radius);
        }
    }
}

module rcube(size=[20,20,20], rounding_radius=1)
{
    hull()
    for(x=[-(size[0]/2-rounding_radius),(size[0]/2-rounding_radius)])
    for(y=[-(size[1]/2-rounding_radius),(size[1]/2-rounding_radius)])
    for(z=[-(size[2]/2-rounding_radius),(size[2]/2-rounding_radius)])
    translate([x,y,z])
    sphere(r=rounding_radius);
}

module cylindera(
        h=10,
        r=undef,
        r1=undef,
        r2=undef,
        d=undef,
        d1=undef,
        d2=undef,
        align=[0,0,0],
        orient=[0,0,1],
        extra_h=0,
        extra_r=undef,
        extra_d=undef,
        extra_align=[0,0,1],
        round_radius=undef,
        debug=false
        )
{
    pi=3.1415926536;

    useDia = r == undef && (r1 == undef && r2 == undef);

    r1_ = useDia?((d1==undef?undef:d1)/2):r1;
    r2_ = useDia?((d2==undef?undef:d2)/2):r2;
    r_= useDia?d/2:(r==undef?0:r);
    r1r2max = max(r1,r2) == undef ? max(d1,d2)/2 : max(r1,r2);
    r__ = r_==undef? r1r2max : r_;
    extra_r_ = useDia?((extra_d==undef?0:extra_d)/2):((extra_r==undef)?0:extra_r);

    sizexy=r__*2;
    extra_sizexy=extra_r_*2;

    // some orient hax here to properly support extra_align
    orient(-orient)
    size_align([extra_sizexy,extra_sizexy,extra_h], align=extra_align, orient=orient)
    orient(orient)
    {
        if(debug)
        {
            echo(useDia, h, r_, r1_, r2_, extra_r_, align);
        }

        // some orient hax here to properly support extra_align
        orient(-orient)
        size_align([sizexy,sizexy,h], align=align, orient=orient)
        {
            if(round_radius==undef)
            {
                cylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, center=true);
            }
            else
            {
                rcylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, round_radius=round_radius);
            }
        }
    }
}

/*translate([10,0,0])*/
/*rotate_extrude()*/
        /*translate([10-2,2,0])*/
/*$fa = 5.6;*/
/*$fs = 0.3;*/
/*circle(r = 100);*/
/*torus(10, 2, align=[0,0,0], orient=[0,0,1]);*/

module torus(radius, radial_width, align=[0,0,0], orient=[0,0,1])
{
    size_align(size=[radius*2+radial_width*2, radius*2+radial_width*2, radial_width*2], align=align, orient=orient)
    rotate_extrude()
    translate([radius, 0, 0])
    circle(radial_width);
}

module rcylinder(d=undef, r1=undef, r2=undef, h=10, round_radius=2)
{
    useDia = r == undef && (r1 == undef && r2 == undef);

    r1_ = useDia?((d1==undef?undef:d1)/2):r1;
    r2_ = useDia?((d2==undef?undef:d2)/2):r2;
    r_= useDia?[d/2,d/2]:(r==undef?[r1_,r2_]:[r,r]);
    /*translate([0,0,-h/2])*/
    hull()
    {
        /*a = r_[0]-r_[1];*/
        /*b = h;*/
        /*c = pythag_hyp(a,b);*/
        /*echo(c);*/
        /*d = c;//pythag_leg(a,c);*/
        /*echo(d);*/
        /*translate([0,r1-round_radius,0])*/
        /*cube([d,d,d]);*/
        /*angle2 = -atan2(-h, r1-r2);*/
        /*echo(angle2);*/
        /*x2 = r2-r1 < 0 ? (round_radius*2*cos(angle2)) : (round_radius*2*sin(angle2));*/
        /*echo(x2)*/
        /*translate([0, 0, h/2-round_radius])*/
        /*torus(radius=r_[1]-round_radius, radial_width=round_radius, align=[0,0,0]);*/

        for(z=[-1,1])
        translate([0, 0, z*(-h/2)])
        {
            /*rd = abs(r1-r2);*/
            /*angle1 = atan2(h, abs(r2-r1));*/
            /*x1 = round_radius*2*cos(angle1);*/
            /*echo(angle1, x1);*/
            r__=z!=-1?r_[0]:r_[1];
            torus(radius=r__-round_radius/2, radial_width=round_radius/4, align=[0,0,z]);

            /*translate([0, 0, -round_radius])*/
            /*cubea([r__*2,r__*2,5], align=[0,0,-z]);*/
        }
    }
}

module pie_slice_shape(r, start_angle, end_angle) {
    R = r * sqrt(2) + 1;
    a0 = (4 * start_angle + 0 * end_angle) / 4;
    a1 = (3 * start_angle + 1 * end_angle) / 4;
    a2 = (2 * start_angle + 2 * end_angle) / 4;
    a3 = (1 * start_angle + 3 * end_angle) / 4;
    a4 = (0 * start_angle + 4 * end_angle) / 4;
    if(end_angle > start_angle)
    {
        intersection() {
            circle(r);
            polygon([
                    [0,0],
                    [R * cos(a0), R * sin(a0)],
                    [R * cos(a1), R * sin(a1)],
                    [R * cos(a2), R * sin(a2)],
                    [R * cos(a3), R * sin(a3)],
                    [R * cos(a4), R * sin(a4)],
                    [0,0]
            ]);
        }
    }
}

module pie_slice(r, start_angle, end_angle, h)
{
    linear_extrude(h)
    {
        pie_slice_shape(r, start_angle, end_angle);
    }
}

module hollow_cylinder(d=10, thickness=1, h=10, taper=false, taper_h=undef, orient=[0,0,1], align=[0,0,0])
{
    outer_d = d+thickness/2;
    inner_d = d-thickness/2;
    size_align(size=[outer_d, outer_d, h], orient=orient, align=align)
    difference()
    {
        /*hull()*/
        union()
        {
            cylindera(h=h-taper_h*2, d=outer_d, orient=[0,0,1], align=[0,0,0]);
            taper_h = taper_h == undef ? (outer_d-inner_d)/4 : taper_h;
            /*taper_h_ = pythag_leg(taper_h, outer_d-inner_d);*/
            /*echo(taper_h_);*/
            if(taper)
            {
                for(z=[-1,1])
                translate([0,0,z*(h/2-taper_h)])
                mirror([0,0,z==-1?1:0])
                difference()
                {
                    cylindera(d1=outer_d, d2=outer_d-inner_d/4, h=taper_h*2, align=[0,0,1]);
                    cylindera(d1=inner_d, d2=outer_d, h=taper_h*2+.1, align=[0,0,1]);
                }
            }
        }

        cylindera(h=h+.4, d=inner_d, orient=[0,0,1], align=[0,0,0]);
    }
}

/*hollow_cylinder(thickness=5, h=10, taper=true, orient=[0,0,1], align=[0,0,1]);*/
/*cylindera(d=10, h=10, orient=[0,0,1], align=[0,0,1]);*/
/*translate([10,0,0])*/
/*{*/
    /*hollow_cylinder(d=10, thickness=4, h=10, taper=true, taper_h=.5, orient=[0,0,1], align=[0,0,1]);*/
    /*cylindera(d=8, h=10, orient=[0,0,1], align=[0,0,1]);*/
/*}*/

/*%pie_slice(r=10, start_angle=-30, end_angle=270, h=10);*/

/*cubea([10,10,10],[1,0,0]);*/
/*%cubea([10,10,10],[1,0,0],[5,5,5],[1,1,1]);*/

/*%cubea([10,10,10],[-1,0,1]);*/
/*%cubea([10,10,10],[-1,0,1],[1,1,1],[-1,0,1]);*/
/*%cylindera(h=10, r=10/2, align=[-1,1,1], extra_r=5/2, extra_h=2, extra_align=[-1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[-1,1,1], extra_d=5, extra_h=2, extra_align=[-1,1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=15, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,-1,1], extra_d=5, extra_h=2, extra_align=[-1,-1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=5, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,0,0], extra_d=10);*/

/*hull_pairwise()*/
{
    /*sphere(30/2);*/

/*translate([30,0,0])*/
    /*rcubea(s=[35,35,35], rounding_radius=10);*/
    /*rcubea(s=[35,35,35], align=[0,-1,0]);*/

/*translate([60,0,0])*/
    /*sphere(30/2);*/
}

use <misc.scad>
use <transforms.scad>

module cubea(size=[10,10,10], align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cube(size+extrasize, center=true);
        }
    }
}

module rcubea(size=[10,10,10], facets=32, rounding_radius=1, align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            rcube(size=size+extrasize, facets=facets, rounding_radius=rounding_radius);
        }
    }
}

module rcube(size=[20,20,20], rounding_radius=1)
{
    hull()
    for(x=[-(size[0]/2-rounding_radius),(size[0]/2-rounding_radius)])
    for(y=[-(size[1]/2-rounding_radius),(size[1]/2-rounding_radius)])
    for(z=[-(size[2]/2-rounding_radius),(size[2]/2-rounding_radius)])
    translate([x,y,z])
    sphere(r=rounding_radius);
}

module cylindera(
        h=10,
        r=undef,
        r1=undef,
        r2=undef,
        d=undef,
        d1=undef,
        d2=undef,
        align=[0,0,0],
        orient=[0,0,1],
        extra_h=0,
        extra_r=undef,
        extra_d=undef,
        extra_align=[0,0,1],
        round_radius=undef,
        debug=false
        )
{
    pi=3.1415926536;

    useDia = r == undef && (r1 == undef && r2 == undef);

    r1_ = useDia?((d1==undef?undef:d1)/2):r1;
    r2_ = useDia?((d2==undef?undef:d2)/2):r2;
    r_= useDia?d/2:(r==undef?0:r);
    r1r2max = max(r1,r2) == undef ? max(d1,d2)/2 : max(r1,r2);
    r__ = r_==undef? r1r2max : r_;
    extra_r_ = useDia?((extra_d==undef?0:extra_d)/2):((extra_r==undef)?0:extra_r);

    sizexy=r__*2;
    extra_sizexy=extra_r_*2;

    // some orient hax here to properly support extra_align
    orient(-orient)
    size_align([extra_sizexy,extra_sizexy,extra_h], align=extra_align, orient=orient)
    orient(orient)
    {
        if(debug)
        {
            echo(useDia, h, r_, r1_, r2_, extra_r_, align);
        }

        // some orient hax here to properly support extra_align
        orient(-orient)
        size_align([sizexy,sizexy,h], align=align, orient=orient)
        {
            if(round_radius==undef)
            {
                cylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, center=true);
            }
            else
            {
                rcylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, round_radius=round_radius);
            }
        }
    }
}

/*translate([10,0,0])*/
/*rotate_extrude()*/
        /*translate([10-2,2,0])*/
/*$fa = 5.6;*/
/*$fs = 0.3;*/
/*circle(r = 100);*/
/*torus(10, 2, align=[0,0,0], orient=[0,0,1]);*/

module torus(radius, radial_width, align=[0,0,0], orient=[0,0,1])
{
    size_align(size=[radius*2+radial_width*2, radius*2+radial_width*2, radial_width*2], align=align, orient=orient)
    rotate_extrude()
    translate([radius, 0, 0])
    circle(radial_width);
}

module rcylinder(d=10, r1=undef, r2=undef, h=10, round_radius=2)
{
    r_= (r1!=undef && r2!=undef) ? [r1,r2] : [d/2,d/2];
    /*translate([0,0,-h/2])*/
    hull()
    {
        /*a = r_[0]-r_[1];*/
        /*b = h;*/
        /*c = pythag_hyp(a,b);*/
        /*echo(c);*/
        /*d = c;//pythag_leg(a,c);*/
        /*echo(d);*/
        /*translate([0,r1-round_radius,0])*/
        /*cube([d,d,d]);*/
        /*angle2 = -atan2(-h, r1-r2);*/
        /*echo(angle2);*/
        /*x2 = r2-r1 < 0 ? (round_radius*2*cos(angle2)) : (round_radius*2*sin(angle2));*/
        /*echo(x2)*/
        /*translate([0, 0, h/2-round_radius])*/
        /*torus(radius=r_[1]-round_radius, radial_width=round_radius, align=[0,0,0]);*/

        for(z=[-1,1])
        translate([0, 0, z*(-h/2)])
        {
            /*rd = abs(r1-r2);*/
            /*angle1 = atan2(h, abs(r2-r1));*/
            /*x1 = round_radius*2*cos(angle1);*/
            /*echo(angle1, x1);*/
            r__=z!=-1?r_[0]:r_[1];
            torus(radius=r__-round_radius/2, radial_width=round_radius/2, align=[0,0,z]);

            /*translate([0, 0, -round_radius])*/
            /*cubea([r__*2,r__*2,5], align=[0,0,-z]);*/
        }
    }
}

module pie_slice_shape(r, start_angle, end_angle) {
    R = r * sqrt(2) + 1;
    a0 = (4 * start_angle + 0 * end_angle) / 4;
    a1 = (3 * start_angle + 1 * end_angle) / 4;
    a2 = (2 * start_angle + 2 * end_angle) / 4;
    a3 = (1 * start_angle + 3 * end_angle) / 4;
    a4 = (0 * start_angle + 4 * end_angle) / 4;
    if(end_angle > start_angle)
    {
        intersection() {
            circle(r);
            polygon([
                    [0,0],
                    [R * cos(a0), R * sin(a0)],
                    [R * cos(a1), R * sin(a1)],
                    [R * cos(a2), R * sin(a2)],
                    [R * cos(a3), R * sin(a3)],
                    [R * cos(a4), R * sin(a4)],
                    [0,0]
            ]);
        }
    }
}

module pie_slice(r, start_angle, end_angle, h)
{
    linear_extrude(h)
    {
        pie_slice_shape(r, start_angle, end_angle);
    }
}

module hollow_cylinder(d=10, thickness=1, h=10, taper=false, taper_h=undef, orient=[0,0,1], align=[0,0,0])
{
    outer_d = d+thickness/2;
    inner_d = d-thickness/2;
    size_align(size=[outer_d, outer_d, h], orient=orient, align=align)
    difference()
    {
        /*hull()*/
        union()
        {
            cylindera(h=h-taper_h/2, d=outer_d, orient=[0,0,1], align=[0,0,0]);
            taper_h = taper_h == undef ? (outer_d-inner_d)/2 : taper_h;
            if(taper)
            {
                for(z=[-1,1])
                translate([0,0,z*(h/2-taper_h/4)])
                mirror([0,0,z==-1?1:0])
                difference()
                {
                    cylindera(d1=outer_d, d2=inner_d, h=taper_h/2, align=[0,0,1]);
                    cylindera(d1=inner_d, d2=inner_d*2, h=taper_h/2+.1, align=[0,0,1]);
                }
            }
        }

        cylindera(h=h+.4, d=inner_d, orient=[0,0,1], align=[0,0,0]);
    }
}

/*hollow_cylinder(thickness=5, h=10, taper=true, orient=[0,0,1], align=[0,0,1]);*/
/*cylindera(d=10, h=10, orient=[0,0,1], align=[0,0,1]);*/
/*translate([10,0,0])*/
/*{*/
    /*hollow_cylinder(d=10, thickness=4, h=10, taper=true, taper_h=.5, orient=[0,0,1], align=[0,0,1]);*/
    /*cylindera(d=8, h=10, orient=[0,0,1], align=[0,0,1]);*/
/*}*/

/*%pie_slice(r=10, start_angle=-30, end_angle=270, h=10);*/

/*cubea([10,10,10],[1,0,0]);*/
/*%cubea([10,10,10],[1,0,0],[5,5,5],[1,1,1]);*/

/*%cubea([10,10,10],[-1,0,1]);*/
/*%cubea([10,10,10],[-1,0,1],[1,1,1],[-1,0,1]);*/
/*%cylindera(h=10, r=10/2, align=[-1,1,1], extra_r=5/2, extra_h=2, extra_align=[-1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[-1,1,1], extra_d=5, extra_h=2, extra_align=[-1,1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=15, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,-1,1], extra_d=5, extra_h=2, extra_align=[-1,-1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=5, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,0,0], extra_d=10);*/

/*hull_pairwise()*/
{
    /*sphere(30/2);*/

/*translate([30,0,0])*/
    /*rcubea(s=[35,35,35], rounding_radius=10);*/

/*translate([60,0,0])*/
    /*sphere(30/2);*/
}


holes swapped, floor flattened, lid fixed

echo("a box with holes in it for Simon");
// todo: get rid of hard-coded '28' in walls_of_box

bigbox = 80;						// old box was 70?
bigboxht = 55;						// up from 50
fatten_for_lid_cut=.2;				// test fit lids: if more than .6 needed, bad geometry or print
									// also, should be zero when printing center section
sides = 2;							// skinny, assumes some further light-stopping material/paint
ledhole=5;
sensorhole=15;
fingerspace=37;
holeside=sensorhole + sides*2 + fingerspace;	// accomodate lense assembly
cornerad=4;						// used with minkowski(), cornerad*2 + 4-flat-sides = perimeter
small_chamber = 1/3;				// total of chambers' ratios should == 1 unless center wall gets thicker
big_chamber = 2/3;				// chambers can be swapped, or center wall can disappear
slit_width = 5;						// mm
cuvtt_inside = 12.1;					// put cuvette into a lid, slide detector assm into lid-grooves, put other lid on.
lid_lad = 5;						// basic lid thickness
lid_puff = 4;						// rounded-ness for lid

module walls_of_box(
			fattener=fatten_for_lid_cut,
			longside=bigbox,
			bigboxht=bigboxht,
			wallthick=sides,
			ledhole=ledhole,
			cornerad=cornerad,
			holeside=holeside,
			insiders_x=bigbox - sides*3 - cornerad*2,
			insiders_y=holeside - cornerad,		// inner-wall corner radius is hard-coded at 1/2 of outer
			){
	echo("longside = ", longside);
	echo("insiders_x = ", insiders_x);
	echo("insiders_y = ", insiders_y);
	difference(){
		minkowski(){
			square([longside - cornerad*2, holeside - cornerad*2], center=true);
			circle(r=cornerad+fattener, $fn=36);
		}
		for(block=[[small_chamber*insiders_x - fattener*2, fattener/2],
					[big_chamber*insiders_x - fattener*2, 28-fattener/2]]){
			echo("block[0] = ", block[0]);
			translate([-longside/2+(wallthick+fattener/2)*2+block[0]/2 + block[1], 0, 0]){
				minkowski(){
					square([block[0], holeside - cornerad - sides*2 - fattener*2], center=true);
					circle(r=(cornerad-fattener)/2, $fn=36);
				}
				// this square is just here to show the light-path
				#square([block[0], slit_width], center=true);
			}
		}
	}
}

module growbox(to_height=bigboxht, slit_width=slit_width, fatboy=0){
	difference(){
		linear_extrude(height = to_height, center = true, convexity = 10, twist = 0, slices = to_height*2, scale = 1){
			walls_of_box(fattener=fatboy+fatten_for_lid_cut);
		}
		// cut the slot for cuvette illumination
		translate([0,0,-5])
			cube([bigbox-sides*2-cornerad, slit_width, to_height - 5], center=true);
		// cut the holes for LED & sensor
		for (i=[[-bigbox/2, sensorhole], [bigbox/2, ledhole]]){
			translate([i[0],0,0]) rotate([0,90,0])
			#cylinder(r=i[1]/2, h=sides*3, center=true, $fn=32);
		}
	}
}

module lids_on_it (overhang=lid_puff, basethick=lid_lad, fatmaker=.35){
	difference(){
		minkowski(){
			cube([bigbox, holeside, basethick], center=true);
			sphere(r=overhang/2, center=true, $fn=32);
		}
		// imprint the base of the walls and cuvette on a lid-like-structure
		translate([0,0,bigboxht/2])
			growbox(fatboy=fatmaker);
		translate([0,0,bigboxht/2])
			cube([cuvtt_inside+.5, cuvtt_inside+.5, bigboxht], center=true);
		// an extra cut to ensure the lid doesn't obscure the cuvett:
		//translate([0,0,bigboxht/2])
		//	cube([bigbox-sides*4, slit_width+.1, bigboxht], center=true);
		if (fatmaker > 0){
			translate([-11,0,bigboxht/2])
				#cube([3,5,bigboxht], center=true);
		}
	}
}

translate([0,holeside+lid_puff+2,(lid_lad+lid_puff)/2])
	lids_on_it();
translate([0,0,(lid_lad+lid_puff)/2])
	lids_on_it(fatmaker=0);
translate([0, 0, (lid_lad+lid_puff)/2 + bigboxht/2])
	growbox();

echo("a box with holes in it for Simon");
// todo: get rid of hard-coded '28' in walls_of_box

bigbox = 80;						// old box was 70?
bigboxht = 55;						// up from 50
fatten_for_lid_cut=.2;				// test fit lids: if more than .6 needed, bad geometry or print
									// also, should be zero when printing center section
sides = 2;							// skinny, assumes some further light-stopping material/paint
ledhole=5;
sensorhole=15;
fingerspace=37;
holeside=sensorhole + sides*2 + fingerspace;	// accomodate lense assembly
cornerad=4;						// used with minkowski(), cornerad*2 + 4-flat-sides = perimeter
small_chamber = 1/3;				// total of chambers' ratios should == 1 unless center wall gets thicker
big_chamber = 2/3;				// chambers can be swapped, or center wall can disappear
slit_width = 5;						// mm
cuvtt_inside = 12.1;					// put cuvette into a lid, slide detector assm into lid-grooves, put other lid on.
lid_lad = 5;						// basic lid thickness
lid_puff = 4;						// rounded-ness for lid

module walls_of_box(
			fattener=fatten_for_lid_cut,
			longside=bigbox,
			bigboxht=bigboxht,
			wallthick=sides,
			ledhole=ledhole,
			cornerad=cornerad,
			holeside=holeside,
			insiders_x=bigbox - sides*3 - cornerad*2,
			insiders_y=holeside - cornerad,		// inner-wall corner radius is hard-coded at 1/2 of outer
			){
	echo("longside = ", longside);
	echo("insiders_x = ", insiders_x);
	echo("insiders_y = ", insiders_y);
	difference(){
		minkowski(){
			square([longside - cornerad*2, holeside - cornerad*2], center=true);
			circle(r=cornerad+fattener, $fn=36);
		}
		for(block=[[small_chamber*insiders_x - fattener*2, fattener/2],
					[big_chamber*insiders_x - fattener*2, 28-fattener/2]]){
			echo("block[0] = ", block[0]);
			translate([-longside/2+(wallthick+fattener/2)*2+block[0]/2 + block[1], 0, 0]){
				minkowski(){
					square([block[0], holeside - cornerad - sides*2 - fattener*2], center=true);
					circle(r=(cornerad-fattener)/2, $fn=36);
				}
				// this square is just here to show the light-path
				#square([block[0], slit_width], center=true);
			}
		}
	}
}

module growbox(to_height=bigboxht, slit_width=slit_width, fatboy=0){
	difference(){
		linear_extrude(height = to_height, center = true, convexity = 10, twist = 0, slices = to_height*2, scale = 1){
			walls_of_box(fattener=fatboy+fatten_for_lid_cut);
		}
		// cut the slot for cuvette illumination
		translate([0,0,-5])
			cube([bigbox-sides*2-cornerad, slit_width, to_height - 5], center=true);
		// cut the holes for LED & sensor
		for (i=[[-bigbox/2, ledhole], [bigbox/2, sensorhole]]){
			translate([i[0],0,0]) rotate([0,90,0])
			#cylinder(r=i[1]/2, h=sides*3, center=true, $fn=64);
		}
	}
}

module lids_on_it (overhang=lid_puff, basethick=lid_lad, fatmaker=.33){
	difference(){
		minkowski(){
			cube([bigbox, holeside, basethick], center=true);
			sphere(r=overhang/2, center=true, $fn=64);
		}
		// imprint the base of the walls and cuvette on a lid-like-structure
		translate([0,0,bigboxht/2])
			growbox(fatboy=fatmaker);
		translate([0,0,bigboxht/2])
			cube([cuvtt_inside+.5, cuvtt_inside+.5, bigboxht], center=true);
		// an extra cut to ensure the lid doesn't obscure the cuvett:
		translate([0,0,bigboxht/2])
			cube([bigbox-sides*4, slit_width+.1, bigboxht], center=true);
	}
}

translate([0,holeside+lid_puff+2,(lid_lad+lid_puff)/2])
	lids_on_it();
translate([0,0,(lid_lad+lid_puff)/2])
	lids_on_it(fatmaker=0);
translate([0, 0, (lid_lad+lid_puff)/2 + bigboxht/2])
	growbox();


bearing: disable taper for ziptie cut

bearing: disable taper for ziptie cut

use <transforms.scad>;
use <shapes.scad>
include <bearing_data.scad>
include <units.scad>
include <misc.scad>

module bearing(bearing_type, extra_h=0, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    h = fallback(override_h, bearing_type[2]) + extra_h;
    size_align(size=[bearing_type[1],bearing_type[1],h], align=align ,orient=orient)
    difference()
    {
        // outer
        cylindera(h=h, d=bearing_type[1], align=[0,0,0]);
        // inner
        cylindera(h=h+.1, d=bearing_type[0], align=[0,0,0]);
        // clips
        if(len(bearing_type) > 3)
        {
            clip_depth=.5;
            for(z=[-1,1])
            translate([0,0,z*bearing_type[3]/2])
            difference()
            {
                cylindera(h=1*mm, d=bearing_type[2]+1, align=[0,0,-z]);
                cylindera(h=1*mm+.1, d=bearing_type[4]-clip_depth, align=[0,0,-z]);
            }

        }
    }
}

module bearing_mount_holes(bearing_type, ziptie_type=[2*mm, 3*mm], ziptie_bearing_distance=3*mm, tolerance=1.01, orient=[1,0,0], ziptie_dist=undef, with_zips=true, show_zips=false)
{
    ziptie_thickness = ziptie_type[0];
    ziptie_width = ziptie_type[1]+0.6*mm;

    ziptie_dist_ = fallback(ziptie_dist, bearing_type[3]/2);

    orient(orient)
    {
        // Main bearing cut
        cylindera(h=bearing_type[2]*tolerance, d=bearing_type[1]*tolerance, orient=[0,0,1]);

        if(with_zips)
        {
            for(z=[-1,1])
                translate([0,0,z*ziptie_dist_ - z*1/2])
                    hollow_cylinder(
                            d=bearing_type[1]+ziptie_bearing_distance+ziptie_thickness,
                            thickness = ziptie_thickness*2,
                            h = ziptie_width,
                            taper=false,
                            orient=[0,0,1],
                            align=[0,0,0]
                            );
        }

        // for linear rod
        cylindera(d=bearing_type[0]+1*mm, h=100, orient=[0,0,1]);

        if(show_zips)
        {
            for(z=[-1,1])
            translate([0,0,z*ziptie_dist_])
            {
                %hollow_cylinder(
                        d=bearing_type[1]+ziptie_bearing_distance+ziptie_thickness,
                        thickness = ziptie_thickness,
                        h = ziptie_width,
                        taper=false,
                        orient=[0,0,1],
                        align=[0,0,-z]
                        );
            }
        }
    }
}

if(false)
{
    b=bearing_igus_rj4jp_01_12;
    bearing_mount_holes(b, orient=[0,0,1]);
    translate([30,0,0])
    bearing(b, orient=[0,0,1]);
}

use <transforms.scad>;
use <shapes.scad>
include <bearing_data.scad>
include <units.scad>
include <misc.scad>

module bearing(bearing_type, extra_h=0, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    h = fallback(override_h, bearing_type[2]) + extra_h;
    size_align(size=[bearing_type[1],bearing_type[1],h], align=align ,orient=orient)
    difference()
    {
        // outer
        cylindera(h=h, d=bearing_type[1], align=[0,0,0]);
        // inner
        cylindera(h=h+.1, d=bearing_type[0], align=[0,0,0]);
        // clips
        if(len(bearing_type) > 3)
        {
            clip_depth=.5;
            for(z=[-1,1])
            translate([0,0,z*bearing_type[3]/2])
            difference()
            {
                cylindera(h=1*mm, d=bearing_type[2]+1, align=[0,0,-z]);
                cylindera(h=1*mm+.1, d=bearing_type[4]-clip_depth, align=[0,0,-z]);
            }

        }
    }
}

module bearing_mount_holes(bearing_type, ziptie_type=[2*mm, 3*mm], ziptie_bearing_distance=3*mm, tolerance=1.01, orient=[1,0,0], ziptie_dist=undef, with_zips=true, show_zips=false)
{
    ziptie_thickness = ziptie_type[0];
    ziptie_width = ziptie_type[1]+0.6*mm;

    ziptie_dist_ = fallback(ziptie_dist, bearing_type[3]/2);

    orient(orient)
    {
        // Main bearing cut
        cylindera(h=bearing_type[2]*tolerance, d=bearing_type[1]*tolerance, orient=[0,0,1]);

        if(with_zips)
        {
            for(z=[-1,1])
                translate([0,0,z*ziptie_dist_ - z*1/2])
                    hollow_cylinder(
                            d=bearing_type[1]+ziptie_bearing_distance+ziptie_thickness,
                            thickness = ziptie_thickness*2,
                            h = ziptie_width,
                            taper=true,
                            orient=[0,0,1],
                            align=[0,0,0]
                            );
        }

        // for linear rod
        cylindera(d=bearing_type[0]+1*mm, h=100, orient=[0,0,1]);

        if(show_zips)
        {
            for(z=[-1,1])
            translate([0,0,z*ziptie_dist_])
            {
                %hollow_cylinder(
                        d=bearing_type[1]+ziptie_bearing_distance+ziptie_thickness,
                        thickness = ziptie_thickness,
                        h = ziptie_width,
                        taper=true,
                        orient=[0,0,1],
                        align=[0,0,-z]
                        );
            }
        }
    }
}

if(false)
{
    b=bearing_igus_rj4jp_01_12;
    bearing_mount_holes(b, orient=[0,0,1]);
    translate([30,0,0])
    bearing(b, orient=[0,0,1]);
}


shapes: add cuberounda

shapes: add cuberounda

use <misc.scad>

// translate children
module lineup(arr=undef)
{
    /*echo(arr);*/
    /*echo($children);*/
    if($children>0)
    {
        for (i = [0 : $children-1])
            translate(arr[i]) children(i);
    }
}

module stack(separations)
{
    union()
    {
        for (i = [0:len(separations)-1])
        {
            offset = v_sum(separations,i);
            /*echo("i",i,"offset",offset);*/
            translate ([0,0,offset])
            {
                child(i);
            }
        }
    }
}

module orient(zaxes, roll=0)
{
    zaxes = len(zaxes.x) == undef && zaxes.x != undef? [zaxes] : zaxes;
    for(zaxis=zaxes)
    {
        rotate(_orient_angles(zaxis))
        /*rotate(roll*z)*/
            children();
    }
}

module size_align(size=[10,10,10], align=[0,0,0], orient=[0,0,1])
{
    bounds = _rotate_matrix(_orient_angles(orient)) * [size.x,size.y,size.z,1];
    t=hadamard(align, [abs(bounds.x/2),abs(bounds.y/2),abs(bounds.z/2)]);
    translate(t)
    {
        orient(orient)
        {
            children();
        }
    }
}

module cubea(size=[10,10,10], align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cube(size+extrasize, center=true);
        }
    }
}

module cuberounda(size=[10,10,10], facets=32, rounding_radius=1, align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cuberound(size=size+extrasize, facets=facets, rounding_radius=rounding_radius);
        }
    }
}

module cuberound(size=[10,10,10], facets=32, rounding_radius=1)
{
    translate(-size/2)
    hull()
    {
        translate([rounding_radius,rounding_radius,rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([size[0]-rounding_radius,rounding_radius,rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([rounding_radius,size[1]-rounding_radius,rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([size[0]-rounding_radius,size[1]-rounding_radius,rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([rounding_radius,rounding_radius,size[2]-rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([size[0]-rounding_radius,rounding_radius,size[2]-rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([rounding_radius,size[1]-rounding_radius,size[2]-rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([size[0]-rounding_radius,size[1]-rounding_radius,size[2]-rounding_radius]) sphere (r=rounding_radius,$fn=facets);
    }
}

module cylindera(h=10, r=undef, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, align=[0,0,0], extra_h=0,extra_r=undef,extra_d=undef,extra_align=[0,0,0])
{
    extra_r_=(extra_r==undef?0:extra_r);
    extra_d_=(extra_d==undef?0:extra_d);
    extra_sizexy=extra_r_*2 + extra_d_;
    size_align([extra_sizexy,extra_sizexy,extra_h],extra_align)
    {
        r_=(r==undef?0:r);
        d_=(d==undef?0:d);
        sizexy=r_*2 + d_;
        size_align([sizexy,sizexy,h],align)
        {
            cylinder(h=h+extra_h, r=r+extra_r_, r1=r1, r2=r2, d=d+extra_d_, d1=d1, d2=d2, center=true);
        }
    }
}

module fncylinder(r, r2, d, d2, h, fn, center=false, enlarge=0, fnr=0.8){
    translate(center==false?[0,0,-enlarge]:[0,0,-h/2-enlarge]) {
        if (fn==undef) {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            }
        } else {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=fn);
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=fn);
            }
        }
    }
}

// specify segment length with fnr, $fn not needed but if desired use fn instead but if desired use fn instead
module fncylindera(
        h=10,
        r=undef,
        r1=undef,
        r2=undef,
        d=undef,
        d1=undef,
        d2=undef,
        align=[0,0,0],
        orient=[0,0,1],
        extra_h=0,
        extra_r=undef,
        extra_d=undef,
        extra_align=[0,0,1],
        fn,
        fnr=0.8,
        debug=false
        )
{
    pi=3.1415926536;

    useDia = r == undef && (r1 == undef && r2 == undef);

    r_= useDia?d/2:(r==undef?0:r);
    r1_ = useDia?((d1==undef?undef:d1)/2):r1;
    r2_ = useDia?((d2==undef?undef:d2)/2):r2;
    extra_r_ = useDia?((extra_d==undef?0:extra_d)/2):((extra_r==undef)?0:extra_r);

    sizexy=r_*2;
    extra_sizexy=extra_r_*2;

    // some orient hax here to properly support extra_align
    orient(-orient)
    size_align([extra_sizexy,extra_sizexy,extra_h], align=extra_align, orient=orient)
    orient(orient)
    {
        fn_=fn==undef?(floor(2*(r_+extra_r_)*pi/fnr)):fn;

        if(debug)
        {
            echo(useDia, h, r_, r1_, r2_, extra_r_, align, fn_);
        }

        // some orient hax here to properly support extra_align
        orient(-orient)
        size_align([sizexy,sizexy,h], align=align, orient=orient)
        {
            cylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, center=true, $fn=fn_);
        }
    }
}

module pie_slice_shape(r, start_angle, end_angle) {
    R = r * sqrt(2) + 1;
    a0 = (4 * start_angle + 0 * end_angle) / 4;
    a1 = (3 * start_angle + 1 * end_angle) / 4;
    a2 = (2 * start_angle + 2 * end_angle) / 4;
    a3 = (1 * start_angle + 3 * end_angle) / 4;
    a4 = (0 * start_angle + 4 * end_angle) / 4;
    if(end_angle > start_angle)
    {
        intersection() {
            circle(r);
            polygon([
                    [0,0],
                    [R * cos(a0), R * sin(a0)],
                    [R * cos(a1), R * sin(a1)],
                    [R * cos(a2), R * sin(a2)],
                    [R * cos(a3), R * sin(a3)],
                    [R * cos(a4), R * sin(a4)],
                    [0,0]
            ]);
        }
    }
}

module pie_slice(r, start_angle, end_angle, h)
{
    linear_extrude(h)
    {
        pie_slice_shape(r, start_angle, end_angle);
    }
}

/*%pie_slice(r=10, start_angle=-30, end_angle=270, h=10);*/

/*cubea([10,10,10],[1,0,0]);*/
/*%cubea([10,10,10],[1,0,0],[5,5,5],[1,1,1]);*/

/*%cubea([10,10,10],[-1,0,1]);*/
/*%cubea([10,10,10],[-1,0,1],[1,1,1],[-1,0,1]);*/
/*%cylindera(h=10, r=10/2, align=[-1,1,1], extra_r=5/2, extra_h=2, extra_align=[-1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[-1,1,1], extra_d=5, extra_h=2, extra_align=[-1,1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=15, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,-1,1], extra_d=5, extra_h=2, extra_align=[-1,-1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=5, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,0,0], extra_d=10);*/
/*fncylindera(h=10, r=5, extra_r=2, align=[0,0,1], orient=[1,0,0]);*/

/*fncylindera(h=10, d=5, extra_r=2, align=[0,0,-1], orient=[0,0,1]);*/
/*translate([0,-10,0])*/
/*fncylindera(h=10, d=5, extra_r=2, align=[0,0,1], orient=[0,0,1]);*/
/*translate([0,-20,0])*/
/*fncylindera(h=10, d=10, extra_h=5, orient=[1,0,0], align=[1,0,0], extra_align=[1,0,0]);*/
/*translate([0,-30,0])*/
/*fncylindera(h=10, d=7.5, extra_h=5, orient=[1,0,0], align=[-1,0,0], extra_align=[1,0,0]);*/

use <misc.scad>

// translate children
module lineup(arr=undef)
{
    /*echo(arr);*/
    /*echo($children);*/
    if($children>0)
    {
        for (i = [0 : $children-1])
            translate(arr[i]) children(i);
    }
}

module stack(separations)
{
    union()
    {
        for (i = [0:len(separations)-1])
        {
            offset = v_sum(separations,i);
            /*echo("i",i,"offset",offset);*/
            translate ([0,0,offset])
            {
                child(i);
            }
        }
    }
}

module orient(zaxes, roll=0)
{
    zaxes = len(zaxes.x) == undef && zaxes.x != undef? [zaxes] : zaxes;
    for(zaxis=zaxes)
    {
        rotate(_orient_angles(zaxis))
        /*rotate(roll*z)*/
            children();
    }
}

module size_align(size=[10,10,10], align=[0,0,0], orient=[0,0,1])
{
    bounds = _rotate_matrix(_orient_angles(orient)) * [size.x,size.y,size.z,1];
    t=hadamard(align, [abs(bounds.x/2),abs(bounds.y/2),abs(bounds.z/2)]);
    translate(t)
    {
        orient(orient)
        {
            children();
        }
    }
}

module cubea(size=[10,10,10], align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cube(size+extrasize, center=true);
        }
    }
}

module cylindera(h=10, r=undef, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, align=[0,0,0], extra_h=0,extra_r=undef,extra_d=undef,extra_align=[0,0,0])
{
    extra_r_=(extra_r==undef?0:extra_r);
    extra_d_=(extra_d==undef?0:extra_d);
    extra_sizexy=extra_r_*2 + extra_d_;
    size_align([extra_sizexy,extra_sizexy,extra_h],extra_align)
    {
        r_=(r==undef?0:r);
        d_=(d==undef?0:d);
        sizexy=r_*2 + d_;
        size_align([sizexy,sizexy,h],align)
        {
            cylinder(h=h+extra_h, r=r+extra_r_, r1=r1, r2=r2, d=d+extra_d_, d1=d1, d2=d2, center=true);
        }
    }
}

module fncylinder(r, r2, d, d2, h, fn, center=false, enlarge=0, fnr=0.8){
    translate(center==false?[0,0,-enlarge]:[0,0,-h/2-enlarge]) {
        if (fn==undef) {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            }
        } else {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=fn);
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=fn);
            }
        }
    }
}

// specify segment length with fnr, $fn not needed but if desired use fn instead but if desired use fn instead
module fncylindera(
        h=10,
        r=undef,
        r1=undef,
        r2=undef,
        d=undef,
        d1=undef,
        d2=undef,
        align=[0,0,0],
        orient=[0,0,1],
        extra_h=0,
        extra_r=undef,
        extra_d=undef,
        extra_align=[0,0,1],
        fn,
        fnr=0.8,
        debug=false
        )
{
    pi=3.1415926536;

    useDia = r == undef && (r1 == undef && r2 == undef);

    r_= useDia?d/2:(r==undef?0:r);
    r1_ = useDia?((d1==undef?undef:d1)/2):r1;
    r2_ = useDia?((d2==undef?undef:d2)/2):r2;
    extra_r_ = useDia?((extra_d==undef?0:extra_d)/2):((extra_r==undef)?0:extra_r);

    sizexy=r_*2;
    extra_sizexy=extra_r_*2;

    // some orient hax here to properly support extra_align
    orient(-orient)
    size_align([extra_sizexy,extra_sizexy,extra_h], align=extra_align, orient=orient)
    orient(orient)
    {
        fn_=fn==undef?(floor(2*(r_+extra_r_)*pi/fnr)):fn;

        if(debug)
        {
            echo(useDia, h, r_, r1_, r2_, extra_r_, align, fn_);
        }

        // some orient hax here to properly support extra_align
        orient(-orient)
        size_align([sizexy,sizexy,h], align=align, orient=orient)
        {
            cylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, center=true, $fn=fn_);
        }
    }
}

module pie_slice_shape(r, start_angle, end_angle) {
    R = r * sqrt(2) + 1;
    a0 = (4 * start_angle + 0 * end_angle) / 4;
    a1 = (3 * start_angle + 1 * end_angle) / 4;
    a2 = (2 * start_angle + 2 * end_angle) / 4;
    a3 = (1 * start_angle + 3 * end_angle) / 4;
    a4 = (0 * start_angle + 4 * end_angle) / 4;
    if(end_angle > start_angle)
    {
        intersection() {
            circle(r);
            polygon([
                    [0,0],
                    [R * cos(a0), R * sin(a0)],
                    [R * cos(a1), R * sin(a1)],
                    [R * cos(a2), R * sin(a2)],
                    [R * cos(a3), R * sin(a3)],
                    [R * cos(a4), R * sin(a4)],
                    [0,0]
            ]);
        }
    }
}

module pie_slice(r, start_angle, end_angle, h)
{
    linear_extrude(h)
    {
        pie_slice_shape(r, start_angle, end_angle);
    }
}

/*%pie_slice(r=10, start_angle=-30, end_angle=270, h=10);*/

/*cubea([10,10,10],[1,0,0]);*/
/*%cubea([10,10,10],[1,0,0],[5,5,5],[1,1,1]);*/

/*%cubea([10,10,10],[-1,0,1]);*/
/*%cubea([10,10,10],[-1,0,1],[1,1,1],[-1,0,1]);*/
/*%cylindera(h=10, r=10/2, align=[-1,1,1], extra_r=5/2, extra_h=2, extra_align=[-1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[-1,1,1], extra_d=5, extra_h=2, extra_align=[-1,1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=15, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,-1,1], extra_d=5, extra_h=2, extra_align=[-1,-1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=5, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,0,0], extra_d=10);*/
/*fncylindera(h=10, r=5, extra_r=2, align=[0,0,1], orient=[1,0,0]);*/

/*fncylindera(h=10, d=5, extra_r=2, align=[0,0,-1], orient=[0,0,1]);*/
/*translate([0,-10,0])*/
/*fncylindera(h=10, d=5, extra_r=2, align=[0,0,1], orient=[0,0,1]);*/
/*translate([0,-20,0])*/
/*fncylindera(h=10, d=10, extra_h=5, orient=[1,0,0], align=[1,0,0], extra_align=[1,0,0]);*/
/*translate([0,-30,0])*/
/*fncylindera(h=10, d=7.5, extra_h=5, orient=[1,0,0], align=[-1,0,0], extra_align=[1,0,0]);*/


modified bracket - reduced height, increased hole diameter

// units in inches
T_bracket = .2;
T_hole = .5;
T_corner = .6;
T_shell = .15;
L1 = 2.4;
L2 = 1.85;
Hu1 = .8;
Hu2 = 1.55;
Hl1 = 1.35;
Hl2 = 2.1;
W = .85;
D_hole = .25;

module prism(l, w, h){
       polyhedron(
               points=[[0,0,0], [l,0,0], [l,w,0], [0,w,0], [0,w,h], [l,w,h]],
               faces=[[0,1,2,3],[5,4,3,2],[0,4,5,1],[0,3,4],[5,2,1]]
               );
}
difference() {
    union() {
      translate([L1/2,0,0])
        linear_extrude(height = T_bracket)
                square([L1, W], center = true);

      translate([T_bracket/2,0,0])
        linear_extrude(height = L2)
                square([T_bracket, W], center = true);

      translate([T_corner,-W/2,0 ])
        rotate([0,0,90])
            prism(W, T_corner, T_corner);

      translate([L2,-W/2,0 ])
        rotate([0,0,90])
            prism(T_shell, L2, L2);

      translate([L2,W/2-T_shell,0 ])
        rotate([0,0,90])
            prism(T_shell, L2, L2);
    };

    union() {
        translate([Hl1, 0, 0])
            cylinder(h=T_hole,d=D_hole,center=true,$fn=50);

        translate([Hl2, 0, 0])
            cylinder(h=T_hole,d=D_hole,center=true,$fn=50);

        rotate([0,270,0])
            translate([Hu1, 0, 0])
                cylinder(h=T_hole,d=D_hole,center=true,$fn=50);

        rotate([0,270,0])
            translate([Hu2, 0, 0])
                cylinder(h=T_hole,d=D_hole,center=true,$fn=50);
    };
}

// units in inches
T_bracket = .2;
T_hole = .5;
T_corner = .6;
T_shell = .15;
L1 = 2.5;
L2 = 1.85;
Hu1 = .75;
Hu2 = 1.5;
Hl1 = 1.25;
Hl2 = 2;
W = .8;
D_hole = .2;

module prism(l, w, h){
       polyhedron(
               points=[[0,0,0], [l,0,0], [l,w,0], [0,w,0], [0,w,h], [l,w,h]],
               faces=[[0,1,2,3],[5,4,3,2],[0,4,5,1],[0,3,4],[5,2,1]]
               );
}
difference() {
    union() {
      translate([L1/2,0,0])
        linear_extrude(height = T_bracket)
                square([L1, W], center = true);

      translate([T_bracket/2,0,0])
        linear_extrude(height = L2)
                square([T_bracket, W], center = true);

      translate([T_corner,-W/2,0 ])
        rotate([0,0,90])
            prism(W, T_corner, T_corner);

      translate([L2,-W/2,0 ])
        rotate([0,0,90])
            prism(T_shell, L2, L2);

      translate([L2,W/2-T_shell,0 ])
        rotate([0,0,90])
            prism(T_shell, L2, L2);
    };

    union() {
        translate([Hl1, 0, 0])
            cylinder(h=T_hole,d=D_hole,center=true,$fn=50);

        translate([Hl2, 0, 0])
            cylinder(h=T_hole,d=D_hole,center=true,$fn=50);

        rotate([0,270,0])
            translate([Hu1, 0, 0])
                cylinder(h=T_hole,d=D_hole,center=true,$fn=50);

        rotate([0,270,0])
            translate([Hu2, 0, 0])
                cylinder(h=T_hole,d=D_hole,center=true,$fn=50);
    };
}


increased precision of the side wall finish

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

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

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

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

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

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

  cut_in_frame()
    children();
}

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

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

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

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

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

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

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

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

  cut_in_frame()
    children();
}

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

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


Dual E3D V6 + extruder mount prototype.  Not meant for BG7.

hole_sep = 30;
hole_sep_2 = 20;
slop = .1;
lower_hole_sep = 30;
lower_hole_rad = 5.5+slop;
lower_hole_height = -7.5;

%cube([9,9,100],center=true);

wall=4;
m_thickness = wall*2+1+1;
hotend_attachment_rad = 23;

//hotend stuff
hotend_rad = 8+slop;

//standard stuff
bolt_slop = .5;
nut_slop = .85;
bolt_dia = 5+bolt_slop;
bolt_rad = bolt_dia/2;
bolt_cap_dia = 10+bolt_slop;
bolt_cap_rad = bolt_cap_dia/2;
nut_dia = 9+nut_slop;
nut_rad = nut_dia/2;
nut_height = 3.25;
lock_nut_height = 5.25;

m3_nut_rad = 6/cos(30)/2;
m3_nut_height = 3;
m3_rad = 1.8;
m3_cap_rad = 3.25;
m3_cap_height = 2;

632_dia = 3.5;
632_rad = 632_dia/2+slop;
632_nut_rad = 8.25/cos(45)/2;
632_cap_dia = 6.5;
632_cap_rad = 632_cap_dia/2+slop;
632_cap_height = 2+slop;
632_nut_height = 5;

//the radius of the induction sensor
ind_rad = 18/2+slop*2;
ind_offset = -30;
ind_height = 12;

fan_offset = -15;

//not sure why these are needed
arm_rad = wall*1.75;
nut_mount = wall+nut_height/2;	//thickness behind cone
arm_sep = 54;

e3d_fin_rad = 26/2;  //////////23 for the e3d V6; the V5 is 26
echo("Nozzle Sep = ", e3d_fin_rad*2);
//extruder_sep = e3d_fin_rad*2;

//bowden_mount();
//translate([0,25,0]) nut_trap();
//translate([0,50,0]) fan_duct(clip_height=25);
//translate([0,50,0]) fan_duct_induction(clip_height=35, e3d_fin_rad = 26/2); //v5
//translate([0,50,0]) fan_duct_induction(clip_height=25, e3d_fin_rad = 23/2); //v6

//translate([0,-50, 0])
//!cyclops_mount();

inline_mount();

$fn=32;

module nut_trap(){
	difference(){
		union(){
			translate([0,0,wall/6]) cube([hole_sep,wall*2,wall/3], center=true);
			for(i=[0:1]) mirror([i,0,0]) translate([hole_sep/2,0,0]) cylinder(r=632_nut_rad+wall/2,h=632_nut_height, $fn=4);
		}
		for(i=[0:1]) mirror([i,0,0]) translate([hole_sep/2,0,0]){
			translate([0,0,1]) cylinder(r=632_nut_rad,h=632_nut_height, $fn=4);
			translate([0,0,-1]) cylinder(r=632_rad,h=632_nut_height);
		}
	}
}

module fan_duct_induction(clip_height = 40, wire_offset = 4){
        extruder_sep = e3d_fin_rad*2;

    	height = 40;
	fan_w = 40;
	fan_screwhole = 32/2;
	fan_rad = 36/2;

	ductwall = 3.5;

	cutoff = 45;

        unclip_height = 40-clip_height;

        translate([0,0,height/2]) rotate([90,0,0])
	difference(){
                union(){
                    hull(){
			//fan
			translate([0,0,wall/2]) rotate([0,45,0]) translate([0,0,fan_offset]) cube([fan_w, fan_w, wall], center=true);
                        //translate([0,height/2-unclip_height/2,extruder_sep+wall/2+wire_offset]) cube([extruder_sep+e3d_fin_rad*2+ductwall,unclip_height,wall], center=true);

                        //the e3d body, with a gap for the wires to pop up
			for(i=[-1,1]) for(j=[0,wire_offset]) translate([i*extruder_sep/2,0,extruder_sep/2+wall+j]) rotate([90,0,0]) cylinder(r=e3d_fin_rad+ductwall/2, h=height, center=true);

                    }
                    //the induction sensor mount
                    translate([extruder_sep/2,-height/2,extruder_sep/2+wall+wire_offset+ind_offset]) rotate([-90,0,0]) extruder_mount(1, m_height=ind_height, hotend_rad=ind_rad);

		}
                //induction mount
                translate([extruder_sep/2,-height/2,extruder_sep/2+wall+wire_offset+ind_offset]) rotate([-90,0,0]) extruder_mount(0, m_height=ind_height,  hotend_rad=ind_rad);

                //the e3d holes
                #for(i=[-1,1]) translate([i*extruder_sep/2,0,extruder_sep/2+wall+wire_offset]) rotate([90,0,0]) cylinder(r=e3d_fin_rad, h=height+2, center=true);

                hull()
                    for(i=[-1,1]) translate([i*extruder_sep/2-wire_offset/2*i+5*i,0,wall+wire_offset/2]) {
                        rotate([90,0,0]) cylinder(r=wire_offset/2, h=height+ductwall*2, center=true);
                        translate([0,0,5]) rotate([90,0,0]) cylinder(r=wire_offset/2, h=height+ductwall*2, center=true);
                    }

                //cutout around the hotend clamps
                hull(){
                    translate([0,height/2-unclip_height+wall/2,wall+wall]) rotate([0,90,0]) cylinder(r=wall/2, h=100, center=true);
                    translate([0,height/2-unclip_height+wall/2,wall+wall+height]) rotate([0,90,0]) cylinder(r=wall/2, h=100, center=true);
                    translate([0,height,wall+wall]) rotate([0,90,0]) cylinder(r=wall/2, h=100, center=true);
                }

		//cutout for clipping on
                for(i=[0,1]) mirror([i,0,0]) translate([extruder_sep/2,-height/2-.1,extruder_sep/2+wall+wire_offset]){
                     rotate([0,-90+cutoff,0]) difference(){
                        cube([extruder_sep,height+1, extruder_sep]);
                        rotate([-90,0,0]) translate([e3d_fin_rad+ductwall/4,0,-.1]) cylinder(r=ductwall/4, h=height+3, $fn=16);
                    }
                }

		//translate([0,0,50+cutoff]) cube([100,100,100], center=true);
		//cutoff the center
		translate([0,0,50+wall]) cube([extruder_sep,100,100], center=true);

		//fan
                difference(){
                    hull(){
                        translate([0,0,wall/2]) rotate([0,45,0]) translate([0,0,fan_offset-wall/2-.1]) cylinder(r=fan_rad,h=wall);
                        translate([0,0,wall]) cylinder(r=fan_rad,h=.1);
                    }
                     translate([extruder_sep/2,-height/2,extruder_sep/2+wall+wire_offset+ind_offset]) rotate([-90,0,0]) extruder_mount(0, m_height=ind_height,  hotend_rad=ind_rad+1);
                }
                translate([0,0,wall]) cylinder(r=fan_rad,h=wall);

                //fan mount
                translate([0,0,wall/2]) rotate([0,45,0]) translate([0,0,fan_offset]) {
                    for(i=[0:90:359]) rotate([0,0,i]) translate([fan_screwhole, fan_screwhole, -.1]){
                            cylinder(r=m3_rad, h=wall*4, center=true);
                            translate([0,0,wall/2-.1]) cylinder(r1=m3_nut_rad, r2=m3_nut_rad+.5, h=wall*3, $fn=6);
                    }
                }
	}
}

module fan_duct(clip_height = 40, wire_offset = 4){
	height = 40;
	fan_w = 40;
	fan_screwhole = 32/2;
	fan_rad = 36/2;

	ductwall = 3.5;

	cutoff = 40;

        unclip_height = 40-clip_height;

        echo(unclip_height);

	translate([0,0,height/2]) rotate([90,0,0])
	difference(){
                union(){
                    hull(){
			//fan
			translate([0,0,wall/2]) cube([fan_w, fan_w, wall], center=true);
                        //translate([0,height/2-unclip_height/2,extruder_sep+wall/2+wire_offset]) cube([extruder_sep+e3d_fin_rad*2+ductwall,unclip_height,wall], center=true);

			for(i=[-1,1]) for(j=[0,wire_offset]) translate([i*extruder_sep/2,0,extruder_sep/2+wall+j]) rotate([90,0,0]) cylinder(r=e3d_fin_rad+ductwall/2, h=height, center=true);

                    }
                    *hull(){
                         #translate([0,height/2-unclip_height/2,extruder_sep+wall/2+wire_offset]) cube([extruder_sep+e3d_fin_rad*2+ductwall,unclip_height,wall], center=true);
                         #for(i=[-1,1]) translate([i*extruder_sep/2,height/2,extruder_sep/2+wall+wire_offset]) rotate([90,0,0]) cylinder(r=e3d_fin_rad+ductwall/2, h=unclip_height+wall);
                    }
		}

                for(i=[-1,1]) translate([i*extruder_sep/2,0,extruder_sep/2+wall+wire_offset]) rotate([90,0,0]) cylinder(r=e3d_fin_rad, h=height+2, center=true);

                for(i=[-1,1]) translate([i*extruder_sep/2-wire_offset/2*i,0,extruder_sep/2+wall-wire_offset/2]) rotate([90,0,0]) cylinder(r=e3d_fin_rad-wire_offset/2, h=height+ductwall*2, center=true);

                //cutout around the hotend clamps
                //translate([0,height/2-unclip_height/2,wall+height/2+wall/2]) cube([extruder_sep+e3d_fin_rad*3,unclip_height+.1,height], center=true);
                hull(){
                    translate([0,height/2-unclip_height+wall/2,wall+wall]) rotate([0,90,0]) cylinder(r=wall/2, h=100, center=true);
                    translate([0,height/2-unclip_height+wall/2,wall+wall+height]) rotate([0,90,0]) cylinder(r=wall/2, h=100, center=true);
                    translate([0,height,wall+wall]) rotate([0,90,0]) cylinder(r=wall/2, h=100, center=true);
                }

		//cutout for clipping on
                for(i=[0,1]) mirror([i,0,0]) translate([extruder_sep/2,-height/2-.1,extruder_sep/2+wall+wire_offset]){
                     rotate([0,-90+cutoff,0]) difference(){
                        cube([extruder_sep,height+1, extruder_sep]);
                        rotate([-90,0,0]) translate([e3d_fin_rad+ductwall/4,0,-.1]) cylinder(r=ductwall/4, h=height+3, $fn=16);
                    }
                }

		//translate([0,0,50+cutoff]) cube([100,100,100], center=true);
		//cutoff the center
		translate([0,0,50+wall]) cube([extruder_sep,100,100], center=true);

		//fan
		cylinder(r=fan_rad,h=height*2, center=true);
		for(i=[0:90:359]) rotate([0,0,i]) translate([fan_screwhole, fan_screwhole, -.1]){
			cylinder(r=m3_rad, h=wall*4);
			translate([0,0,wall/2-.1]) cylinder(r1=m3_nut_rad, r2=m3_nut_rad+.5, h=wall*4, $fn=6);
		}
	}
}

//mounting holes for the cyclops
module cyclops_holes(solid=0, jut=0){
    hole_sep = 9;
    hole_zsep = 10;
    ind_jut = 2;

    for(i=[0,1]) mirror([i,0,0]){
        translate([hole_sep/2,-wall,hole_zsep]) rotate([-90,0,0]){
            if(solid>=0){
                cylinder(r=m3_rad+wall, h=wall);
                if(jut==1){
                    translate([0,0,wall-.1]) cylinder(r1=m3_rad+wall, r2=m3_rad+wall/2, h=ind_jut+.1);
                }
            }
            if(solid<=0) translate([0,0,-.1]) {
                cap_cylinder(r=m3_rad, h=wall*2);
                cap_cylinder(r=m3_cap_rad, h=m3_cap_height);
            }
        }
    }

    translate([0,-wall,0]) rotate([-90,0,0]){
        if(solid>=0){
            cylinder(r=m3_rad+wall, h=wall);
            if(jut==1){
                translate([0,0,wall-.1]) cylinder(r1=m3_rad+wall, r2=m3_rad+wall/2, h=ind_jut+.1);
            }
        }
        if(solid<=0) translate([0,0,-.1]) {
            %translate([0,-5,9+wall+ind_jut+.1]) cube([30,30,18], center=true);
            %translate([0,-5,6+wall+ind_jut+.1]) rotate([90,0,0]) cylinder(r=1, h=50, center=true);
            cap_cylinder(r=m3_rad, h=wall*2);
            cap_cylinder(r=m3_cap_rad, h=m3_cap_height);
        }
    }
}

module i3_holes(solid=0){
    attach_height=0;
    for(i=[0,1]) mirror([i,0,0]){
        translate([lower_hole_sep/2,-wall,attach_height]) rotate([-90,0,0]){
            if(solid>=0)
                cylinder(r=632_rad+wall, h=wall);
            if(solid<=0) translate([0,0,-.1]) {
                cap_cylinder(r=632_rad, h=wall*2);
                //translate([0,0,wall-632_cap_height])
                translate([0,0,1.5])
                cap_cylinder(r=632_cap_rad, h=632_cap_height+wall);
            }
        }
    }
}

module cyclops_mount(induction=1){
    mount_height = 20;
    e3d_mount_height = wall;
    e3d_mount_offset = 15;
    ind_offset=(16-18)/2;
    wall=4;

    difference(){
        union(){
            hull(){
                for(i=[0,1]) mirror([i,0,0])
                    translate([e3d_mount_offset,0,e3d_mount_height]) cyclops_holes(1, wall=wall);
                translate([0,0,mount_height]) i3_holes(1, wall=wall);
            }
            if(induction==1){
                translate([-e3d_mount_offset,ind_rad+ind_offset,0]) rotate([0,0,90]) extruder_mount(1, m_height=ind_height, hotend_rad=ind_rad, wall=wall);
            }

            translate([e3d_mount_offset,0,e3d_mount_height]) cyclops_holes(1, jut=1, wall=wall);
        }

        translate([e3d_mount_offset,0,e3d_mount_height]) cyclops_holes(-1, wall=wall);
        translate([0,0,mount_height]) i3_holes(-1, wall=wall);
        if(induction==1){
            translate([-e3d_mount_offset,ind_rad+ind_offset,0]) rotate([0,0,90]) extruder_mount(0, m_height=ind_height, hotend_rad=ind_rad, wall=wall);
        }

        //cut off back and base
        translate([0,-50-wall,0]) cube([100,100,100], center=true);
        translate([0,0,-50]) cube([100,100,100], center=true);
    }

}

module inline_mount(height=14){
    extruder_sep = e3d_fin_rad*2;
    attach_height = height+3;

    difference(){
        union(){
            translate([0,e3d_fin_rad-hotend_rad,0]) rotate([0,0,180]) extruder_mount(1,height,0,0);
            translate([extruder_sep,e3d_fin_rad-hotend_rad,0]) rotate([0,0,90]) extruder_mount(1,height,0,0);
            translate([50,e3d_fin_rad-hotend_rad,0]) rotate([0,0,0]) extruder_mount(1,height,0,0, hotend_rad=ind_rad);
        }
        translate([0,e3d_fin_rad-hotend_rad,0]) rotate([0,0,180]) extruder_mount(0,height,0,0);
        translate([extruder_sep,e3d_fin_rad-hotend_rad,0]) rotate([0,0,90]) extruder_mount(0,height,0,0);
        translate([50,e3d_fin_rad-hotend_rad,0]) rotate([0,0,0]) extruder_mount(0,height,0,0, hotend_rad=ind_rad);

        //mounting holes
        for(i=[0,50]) translate([i,0,height/2]) rotate([90,0,0]) {
            #cap_cylinder(r=m3_rad, h=50);
        }
    }
}

module bowden_mount(height=14, induction = 1){
        extruder_sep = e3d_fin_rad*2;
        attach_height = height+3;
	difference(){
		union(){
			for(i=[0,1]) mirror([i,0,0]) translate([extruder_sep/2,e3d_fin_rad-hotend_rad,0]) extruder_mount(1,height,0,0);

			//mount supports
			hull(){
				for(i=[0,1]) mirror([i,0,0]) translate([hole_sep/2,-hotend_rad-wall,attach_height]) rotate([-90,0,0]) cylinder(r=632_rad+wall, h=wall);
				for(i=[0,1]) mirror([i,0,0]) translate([hole_sep/3,-hotend_rad-wall,632_rad+wall]) rotate([-90,0,0]) rotate([0,0,-180/5/2]) cylinder(r=(632_rad+wall)/cos(180/5), h=wall, $fn=5);
			}

			//fillet
			difference(){
				translate([0,-hotend_rad,height+wall/2-.01]) cube([extruder_sep+(hotend_rad/cos(180/18)+.1+wall)/cos(30),wall*2,wall], center=true);
				translate([0, wall/2, wall/2]) translate([0,-hotend_rad+wall/2-.05,height+wall/2-.05]) rotate([0,90,0]) cylinder(r=wall, h=hole_sep+632_rad*2+wall*2+1, center=true);
			}

                        if(induction==1){
                            translate([0,e3d_fin_rad*2-hotend_rad+ind_rad,0]) rotate([0,0,90]) extruder_mount(1, m_height=ind_height, hotend_rad=ind_rad);
                        }
		}
                if(induction==1){
                    translate([0,e3d_fin_rad*2-hotend_rad+ind_rad,0]) rotate([0,0,90]) extruder_mount(0, m_height=ind_height, hotend_rad=ind_rad);
                }

		for(i=[0,1]) mirror([i,0,0]) translate([extruder_sep/2,e3d_fin_rad-hotend_rad,0]) extruder_mount(0,height,0,0);

		//holes
		for(i=[0,1]) mirror([i,0,0]) translate([hole_sep/2,-hotend_rad-wall-.1,attach_height]) rotate([-90,0,0]) {
			cap_cylinder(r=632_rad, h=wall+1);
			//translate([0,0,wall-632_cap_height]) cap_cylinder(r=632_cap_rad, h=wall+1);

			//hollows for other screws on mount
			translate([lower_hole_sep/2-hole_sep/2, -lower_hole_height, 0]) cap_cylinder(r=lower_hole_rad, h=wall+1);
		}

	}
}

module extruder_mount(solid = 1, m_height = 10, fillet = 8, tap_height=0, width=20, fn=6){
	gap = 3;
	tap_dia = 9.1;
	tap_rad = tap_dia/2;

	if(solid){
		//clamp material
		if(m_height > nut_rad*2){
			cylinder(r=(hotend_rad+wall)/cos(30), h=m_height, $fn=fn);
			translate([hotend_rad+bolt_rad+1,gap,m_height/2]) rotate([-90,0,0]) cylinder(r=m_height/2/cos(30), h=wall+1, $fn=6);
			translate([hotend_rad+bolt_rad+1,-wall-1,m_height/2]) rotate([-90,0,0]) cylinder(r=m_height/2/cos(30), h=wall+1, $fn=6);
		}
	}else{
		union(){
			//hotend hole
			translate([0,0,-.05]) cylinder(r=hotend_rad/cos(180/18)+.1, h=m_height+40, $fn=36);

			//bolt slots
			if(m_height > nut_rad*2){
				render() translate([hotend_rad+bolt_rad+2,-m_thickness-.05,m_height/2]) rotate([-90,0,0]) cap_cylinder(r=632_rad, h=m_thickness+10);
				translate([hotend_rad+bolt_rad+2,-wall*2,m_height/2]) rotate([-90,0,0]) cylinder(r=632_nut_rad, h=wall, $fn=4);

				//mount tightener
				translate([hotend_rad+bolt_rad+2,wall+gap-1,m_height/2]) rotate([-90,0,0]) cylinder(r=632_cap_rad, h=10);
				translate([0,0,-.05]) cube([wall*5, gap, m_height+.1]);
			}
		}
	}
}

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

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