Overhaul, added an offset option

Overhaul, added an offset option

This is a major overhaul. Now there are two options (A and B). A is the original; the new one (B) has the bolt offset and a hole for a retaining screw. No glue required. Option A or B can be chosen via the customizer.
Also fixed customizer parameter comments and hid non-customizable variables.

// Hex Bolt Anchor
// Anchor to prevent a hex bolt (or nut) from
// rotating.
// There are two styles:
// style A: Concentric, with washer (the original). Must
//          be glued.
// style B: Offset, without washer, and with hole for
//          retraining screw. The offset prevents
//          the bolt from rotating.
//
// 3/4" - 18 nut dimensions:
//   nut height: 8.45mm // this can vary with nut
//   flat diameter: 14.21mm
//   vertex diameter: 16.23mm (measured)
//   vertex diameter: 16.41mm (calculated from flat diameter)
//   Note that the nut has slightly rounded corners.
//   washer thickness: 1.65mm
//   washer diameter: 20.92mm

// ------- START OF PARAMETERS ---------------------
// Horizontal clearances (mm) so parts drop in easily
clearance = 0.5;

// Exact height of nut
nut_height = 8.45;

// Vertex-to-vertex dia of nut
hex_dia = 16.41;

// Exact dia of washer (style A)
washer_dia = 20.92;

// Exact height of washer
washer_height = 1.89;

// Retaining screw shaft dia (style B only)
screw_dia = 3.53; // #6
// Above is for a flat head screw with a
// 45 degree angle for the head conic section.

// Diameter of screw head (style B only)
screw_head_dia = 7;

// Overall diameter
item_dia = 25.4; // 1 inch

// Extra height above nut and screw
extra_height = 0.2;
// Above helps ensure that nothing sticks out
// above the item - so the item can be made
// flush with the surrounding wood.

// Item style (A is glued, B is screwed)
item_style = "A"; // [A, B]

// -------  END OF PARAMETERS --------------------
module parameter_end(){} // End of customizer parameters

_EPS = 0.1; // for CSG

// Min arc length (for cylinders and spheres)
// This is perfectly fine for 3D printed circles of dia 1".
$fs = 1;
do_A = (item_style == "A");

// Overall height
item_height = nut_height + extra_height + (do_A ? washer_height: 0);

module hex_hole() {
    dia = hex_dia + clearance;
    cylinder(h=item_height + _EPS, r=dia/2, $fn=6);
}

module washer_hole() {
    dia = washer_dia + clearance;
    cylinder(washer_height + _EPS, r=dia/2);
}

module screw_hole() {
    dia1 = screw_dia + clearance;
    dia2 = screw_head_dia + 2*extra_height;
    rdiff = (dia2 - dia1)/2 + clearance;
    cylinder(h=item_height + _EPS, r=dia1/2);
    translate([0, 0, item_height-rdiff+_EPS]) {
    cylinder(h=rdiff, r2=dia2/2, r1=dia1/2);
}
}

// The unit without any holes
module stock() {
    dia = item_dia - clearance;
    cylinder(h=item_height, r=dia/2);
}

module cutout_A() {
    union() {
        translate([0, 0, -_EPS]) hex_hole();
        translate([0, 0, item_height - washer_height])
            washer_hole();
    }
}

module cutout_B() {
    union() {
        // The constants below were obtained by
        // trial-and-error so that the screw hole
        // (with conical section for head) fits
        // within the available space.
        screw_offset = -screw_head_dia*1.24;
        hex_offset = hex_dia*0.14;
        translate([0, hex_offset, -_EPS/2]) hex_hole();
        translate([0, screw_offset, -_EPS/2])screw_hole();
    }
}

module style_A() {
    difference() {
        stock();
        cutout_A();
    }
}

module style_B() {
    difference() {
        stock();
        cutout_B();
    }
}

if (do_A) {
    style_A();
} else {
    style_B();
}

// Hex Bolt Anchor
// Anchor to prevent a hex bolt (or nut) from
// rotating.
//
$fs=1;

// 3/4" - 24 nut dimensions:
//   nut height: 8.27mm
//   flat diameter: 14.21mm
//   vertex diameter: 16.23mm (measured)
//   vertex diameter: 16.41mm (calculated from flat diameter)
//   Note that the nut has slightly rounded corners.
//   washer thickness: 1.65mm
//   washer diameter: 20.92mm
// Model dimensions below add
clearance = 0.5; // mm
nut_height = 8.27;
hex_dia = 16.41+clearance; // Vertex-to-vertex
washer_dia = 20.92+clearance;
washer_height = 1.89; // no vertical clearance - so washer is flush
base_dia = 25.5-clearance; // 1 inch
base_height = nut_height + washer_height;

eps=0.1; // for CSG

module hex(dia, h) {
    cylinder(h=h, r=dia/2, $fn=6);
}

module washer(dia, h) {
    cylinder(h=h, r=dia/2);
}

module base() {
    cylinder(h=base_height, r=base_dia/2);
}

module cutout() {
    union() {
        translate([0, 0, -eps]) hex(hex_dia, base_height+eps);
        translate([0, 0, base_height-washer_height])
            washer(washer_dia, washer_height+eps);
    }
}

module draw0() {
difference() {
    base();
    cutout();
}
}

draw0();


Addign sheshedshed

Addign sheshedshed

shed_length = 5184;
shed_width = 1981;
shed_front_height = 2350;
shed_back_height = 2135;

window_w=1830;
window_h=610;
door_w=870;
door_h=2030;

space_to_window_w=window_w/2;
space_to_window_h=door_h-window_h;
space_to_door_w=window_w + 2*space_to_window_w;

base_timber_w = 47;
base_timber_h = 75;
timber_construct_w = 38;
timber_construct_h = 63;
timber_length_unit=2400;
base_sheet_t = 18;
sheet_width = 1220;
sheet_length = 2440;

wrap_t = 1;

opp = shed_front_height-shed_back_height;
adj = shed_width -timber_construct_h;
hyp = sqrt(opp*opp+adj*adj);
theta = atan(opp/adj);
thin_opp = tan(theta) * timber_construct_h;

module cubeI(size,comment="//", center=false)
{
    if (comment != "//")
        echo(comment);
    // Cube - but will echo dimensions in order of size
    if( (size[0]>size[1]) && (size[1]>=size[2]) )
       echo( size[0], size[1], size[2]);
    if( (size[0]>size[2]) && (size[2]>size[1]) )
       echo( size[0], size[2], size[1]);

    if( (size[1]>size[0]) && (size[0]>=size[2]) )
       echo( size[1], size[0], size[2]);
    if( (size[1]>size[2]) && (size[2]>size[0]) )
       echo( size[1], size[2], size[0]);

    if( (size[2]>size[0]) && (size[0]>=size[1]) )
       echo( size[2], size[0], size[1]);
    if( (size[2]>size[1]) && (size[1]>size[0]) )
       echo( size[2], size[1], size[0]);

    cube(size, center=center);
}

module houseWrapLayer(width,length, overlap=100)
{
    echo("House Wrap",width+overlap,length+overlap);
    color("Black",1)
    {
        cube([width, length, wrap_t]);
        cube([width, wrap_t, overlap]);
        translate([0,length-wrap_t,0]) cube([width, wrap_t, overlap]);
        cube([wrap_t, length, overlap]);
        translate([width-wrap_t,0,0]) cube([wrap_t, length, overlap]);
    }
}

module OSB(size,center=false)
{
    echo("OSB");
    cubeI(size,center=center);
}

module floorPanel(width,length)
{
/*
    echo("Timber");
    //Timber supporting base along left side
    cubeI([base_timber_w, length, base_timber_h]);
    //Timber supporting base along right side
    translate([width-base_timber_w,0,0])  cubeI([base_timber_w, length, base_timber_h]);
    //Timber supporting base Middle of I
    translate([base_timber_w,(length-base_timber_h)/2,base_timber_h-base_timber_w])  cubeI([width-base_timber_w*2, base_timber_h, base_timber_w]);
*/
    //DuPont Tyvek Housewrap - 100m 1.4m
    translate([0,0,base_timber_h]) houseWrapLayer(width,length,overlap=25);

    //OSB Board - although the board is not cut by 1 mm (wrap_t) in each
    //              direction for drawing purposes it is shaved
    translate([wrap_t,wrap_t,base_timber_h+wrap_t]) OSB([width-wrap_t*2,length-wrap_t*2,base_sheet_t]);
}

module floorBeams(width = shed_width, length = shed_length, overlap = 150, cross_beams=5)
{
    // from one end along the front
    translate([0,0,0]) cubeI([timber_length_unit, base_timber_w, base_timber_h]);
    // from oother end along the front
    translate([length-timber_length_unit, 0, 0]) cubeI([timber_length_unit, base_timber_w, base_timber_h]);
    translate([timber_length_unit-overlap, base_timber_w, 0]) cubeI([length-2*(timber_length_unit-overlap), base_timber_w, base_timber_h]);

    //Again at the back
    // from one end along the front
    translate([0,width-base_timber_w,0]) cubeI([timber_length_unit, base_timber_w, base_timber_h]);
    // from oother end along the front
    translate([length-timber_length_unit, width-base_timber_w, 0]) cubeI([timber_length_unit, base_timber_w, base_timber_h]);
    translate([timber_length_unit-overlap, width-base_timber_w*2, 0]) cubeI([length-2*(timber_length_unit-overlap), base_timber_w, base_timber_h]);

    //Each end of shed
    translate([0, base_timber_w, base_timber_h-base_timber_w]) cubeI([base_timber_h, width-base_timber_w*2, base_timber_w]);
    translate([length-base_timber_h, base_timber_w, base_timber_h-base_timber_w]) cubeI([base_timber_h, width-base_timber_w*2, base_timber_w]);

    // Middle suport
    translate([base_timber_h, (width-base_timber_w)/2, 0]) cubeI([timber_length_unit, base_timber_w, base_timber_h]);
    translate([length-base_timber_h-timber_length_unit, (width-base_timber_w)/2, 0]) cubeI([timber_length_unit, base_timber_w, base_timber_h]);
    translate([timber_length_unit+base_timber_h-overlap, (width-base_timber_w)/2+base_timber_w, 0]) cubeI([length-2*timber_length_unit+overlap, base_timber_w, base_timber_h]);

   // Middle Cross beams0
   translate([(length-base_timber_w)/2-base_timber_h/2, base_timber_w*2, base_timber_h-base_timber_w]) cubeI([base_timber_h, (width-3*base_timber_w)/2, base_timber_w]);
    translate([(length-base_timber_w)/2+base_timber_h/2, base_timber_w*3+(width-3*base_timber_w)/2, base_timber_h-base_timber_w]) cubeI([base_timber_h, (width-3*base_timber_w)/2-2*base_timber_w, base_timber_w]);

}

module floorPanels(width = shed_width, length = shed_length)
{
    sheet_width_inc_wrap = sheet_width + 2*wrap_t;
    num_width_panels = round(-0.5+length/sheet_width_inc_wrap);
    for(base_x = [0 : num_width_panels-1])
    {
        translate([base_x*sheet_width_inc_wrap, 0, 0]) floorPanel(sheet_width_inc_wrap,width);
    }
    full_panels_width = sheet_width_inc_wrap*num_width_panels;
    translate([full_panels_width, 0, 0]) floorPanel(length-full_panels_width,width);
}

module verticalStruts(width, height, beams=0, extra_struct=0)
{
    cubeI([width,timber_construct_h,timber_construct_w]);
    translate([0,0,height-timber_construct_w]) cubeI([width,timber_construct_h,timber_construct_w]);
    translate([0,0,timber_construct_w]) cubeI([timber_construct_w,timber_construct_h,height-timber_construct_w*2]);
    translate([width-timber_construct_w,0,timber_construct_w]) cubeI([timber_construct_w,timber_construct_h,height-timber_construct_w*2]);

    if(beams>0 && extra_struct==0)
    {
        middle_height = height-timber_construct_w*2;
        beam_spacing = middle_height/(beams+1);
        for(loop=[1:beams])
        {
            translate([timber_construct_w, 0, beam_spacing*loop]) cubeI([width-timber_construct_w*2,timber_construct_h,timber_construct_w]);
        }
    }
    if(beams==0 && extra_struct>0)
    {
        middle_width = width-timber_construct_w*1;
        beam_spacing = middle_width/(extra_struct+1);
        for(loop=[1:extra_struct])
        {
            translate([beam_spacing*loop, 0, timber_construct_w]) cubeI([timber_construct_w,timber_construct_h,height-2*timber_construct_w]);
        }
    }
    if(beams>0 && extra_struct>0)
    {
        middle_height = height-timber_construct_w*2;
        beam_spacing_h = middle_height/(beams+1);
        middle_width = width-timber_construct_w*1;
        beam_spacing_w = middle_width/(extra_struct+1);

        // Wee need to off set, so we divide by mod 2
        // move the all the beams down by timber_construct_w
        // but add loop mod 2 * timber_construct_w
        // (hence odd move up, even remain down

        for(loop=[0:extra_struct])
        {
            if (loop>0)
                translate([beam_spacing_w*loop, 0, timber_construct_w]) cubeI([timber_construct_w,timber_construct_h,height-2*timber_construct_w]);
            for(loop_b=[1:beams])
            {
                offset = - timber_construct_w + (timber_construct_w * (loop%2));
                translate([timber_construct_w+beam_spacing_w*loop, 0, beam_spacing_h*loop_b+offset]) cubeI([beam_spacing_w-timber_construct_w,timber_construct_h,timber_construct_w]);
            }
        }
    }
}

module backStructs(width = shed_length, height = shed_back_height, structs_sets=3, beams=2, extra_struct=1)
{
    translate([wrap_t,shed_width-timber_construct_h-wrap_t,base_timber_h+wrap_t+base_sheet_t])
    {
        struct_set_w = (width-wrap_t*2)/structs_sets;
        for(structs=[0:structs_sets-1])
        {
            translate([structs*struct_set_w,0,0]) verticalStruts(struct_set_w, height, beams=beams, extra_struct=extra_struct);
        }
    }

}

module sideStructs(width = shed_width, height = shed_back_height, beams=2, extra_struct=2)
{
    echo("SideStructs");
    translate([timber_construct_h+wrap_t,timber_construct_h,base_timber_h+wrap_t+base_sheet_t])
    {
        rotate([0,0,90]) verticalStruts(width-timber_construct_h*2, height, beams=beams, extra_struct=extra_struct);
    }
}

module leftSideStructs()
{
    sideStructs();
}

module rightSideStructs()
{
    translate([shed_length-timber_construct_h-wrap_t*2,0,0]) sideStructs();
}

module frontStructs()
{
    translate([wrap_t,-wrap_t,base_timber_h+wrap_t+base_sheet_t+1])
    {
        verticalStruts(space_to_window_w, door_h, beams=2, extra_struct=0);
        translate([space_to_window_w,0,0]) verticalStruts(window_w, space_to_window_h, beams=1, extra_struct=1);
        translate([space_to_window_w+window_w,0,0])  verticalStruts(space_to_window_w, door_h, beams=2, extra_struct=1);
        translate([space_to_door_w+door_w,0,0])  verticalStruts(shed_length-(space_to_door_w+door_w), door_h, beams=2, extra_struct=0);
        // top part, which is longer than a standard timber_length_unit
        gap = (space_to_door_w - timber_length_unit)/2;
        remainder = shed_length - timber_length_unit - gap;
        translate([0,0,door_h])  verticalStruts(gap, shed_front_height-door_h, beams=0, extra_struct=0);
        translate([gap,0,door_h])  verticalStruts(timber_length_unit, shed_front_height-door_h, beams=0, extra_struct=2);
        translate([timber_length_unit + gap,0,door_h])  verticalStruts(remainder, shed_front_height-door_h, beams=0, extra_struct=2);
    }
}

module roof()
{
    // hyp
    inner_width = hyp+timber_construct_h;
    flat_offset = (sheet_length - inner_width)/2;

    translate([-flat_offset,-wrap_t,shed_front_height+ base_timber_h+wrap_t+base_sheet_t +1 +thin_opp ]) rotate([-theta,0,0]) frameSheet( sheet_front_offset=-flat_offset*1.5, front_offset=0, back_offset=flat_offset*2, left_offset=flat_offset);
}

module frameSheet(left_offset=0, right_offset=0, front_offset=0, back_offset=0, sheet_left_offset=0, sheet_right_offset=0, sheet_front_offset=0, sheet_back_offset=0, sw=sheet_width, sl = sheet_length)
{
    translate([left_offset, front_offset, 0]) cubeI([sw-left_offset-right_offset, timber_construct_h, timber_construct_w]);
    translate([left_offset, sl - back_offset-timber_construct_h, 0]) cubeI([sw-left_offset-right_offset, timber_construct_h, timber_construct_w]);
    translate([left_offset, front_offset+timber_construct_h, 0]) cubeI([timber_construct_h, sl-front_offset-back_offset-2*timber_construct_h, timber_construct_w]);
    translate([sw-right_offset-timber_construct_h, front_offset+timber_construct_h, 0]) cubeI([timber_construct_h, sl-front_offset-back_offset-2*timber_construct_h, timber_construct_w]);
    translate([sheet_left_offset, sheet_front_offset, timber_construct_w]) cubeI([sw-sheet_back_offset,sl-sheet_right_offset, base_sheet_t]);
}

floorBeams();

floorPanels();

backStructs();

leftSideStructs();
rightSideStructs();

frontStructs();
roof();

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


Test 3d shapes to measure the strength of 3d printed parts.

6x10cyl.scad - simple cylinder, the latest version - goes into a part made of polycarb. A shearing force causes it to break.

error: pathspec '3dprinting/openscad/test-models/6x10cyl.scad' did not match any file(s) known to git


extruder: use dict_replace_multiple where applicable

include <thing_libutils/metric-thread.scad>;
include <thing_libutils/metric-hexnut.scad>;
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/attach.scad>;
include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>

module capmount(show_sensor=false,lower_height=12,mount_lower=12,height=10,thickness=5,screws_spacing=21,screw_offset=[1,0],screws_diameter=4,sensor_spacing=3,sensor_height=[15,40,5],sensor_diameter=12)

{
    mount_start = 1.7+sensor_spacing+screws_spacing+screws_diameter+2*screw_offset[0];
    if(show_sensor)
    {
        translate([-8+sensor_diameter/2+thickness,-.5+mount_start+thickness+sensor_diameter/2,-39])
        {
            translate([0,0,sensor_height[1]+sensor_height[2]])
                fncylindera(d=sensor_diameter-0.5,h=sensor_height[0]);
            translate([0,0,sensor_height[2]])
                %fncylindera(d=sensor_diameter-0.5,h=sensor_height[1]);
            fncylindera(d=sensor_diameter-0.5,h=sensor_height[2]);
        }
    }

    //  Mount
    $fn=50;
    difference() {
        translate([0,0,-lower_height])
            cube([thickness+1, mount_start, height+lower_height]);

        //Screws 1
        translate([2*e, 4+screw_offset[0], height/2+screw_offset[1]])
        {
            rotate([0,90,0])
            {
                fncylindera(d=screws_diameter, h=thickness+1);
                translate([0,0,2.5])
                    fncylindera(h = 4, d=8.2, $fn=6);
            }
            //Screws 2
            translate([0,screws_spacing,0])
                rotate([0,90,0])
                {
                    fncylindera(d=screws_diameter, h=thickness+1);
                    translate([0,0,2.5])
                        fncylindera(h = 4, d=8.2, $fn=6);
                }
        }

    }
    //Sensor mount
    $fn=200;
    translate([-8,-.3,0])
        difference() {
            union() {
                translate([sensor_diameter/2+thickness,mount_start+thickness+sensor_diameter/2, -lower_height])
                    fncylindera(d=sensor_diameter+2*thickness, h=height+lower_height-mount_lower);

            }
            translate([sensor_diameter/2+thickness,mount_start+thickness+sensor_diameter/2, -height/2])
                fncylindera(d=sensor_diameter+0,5, h=2*height, center=true);

            cutoff=[1,2];
            translate([0,mount_start, -lower_height-e])
                cubea([cutoff[0],sensor_diameter+thickness*2,height+lower_height-mount_lower+2*e],[1,1,1]);

            translate([sensor_diameter+thickness*2,mount_start, -lower_height-e])
                cubea([cutoff[1],sensor_diameter+thickness*2,height+lower_height-mount_lower+2*e],[-1,1,1]);
        }
}

house_bearing=bearing_MR128;
guidler_bearing=bearing_625;

house_padding_wd=11*mm;
house_padding_h=4*mm;

filapath_width=10*mm;

// 4mm ptfe tube
filament_path_d = 4*mm;

// offset from the center of the bolt to the filament path
bolt_center_offset = 4.2*mm;

hotend_mount_h=10.5*mm;

// from E3D V6 heatsink drawing
// http://wiki.e3d-online.com/wiki/File:DRAWING-V6-175-SINK.png
// each entry == dia + h
hotmount_d_h=[[16*mm,3.7*mm],[12*mm,6*mm],[16*mm,3*mm]];
hotmount_outer_size=max(vec_i(hotmount_d_h,0))+10*mm;
hotmount_h_offset=-2*mm;
// which side does hotend slide in (x-axis, i.e. -1 is left, 1 is right)
hotmount_clamp_side=1*mm;

hotmount_tolerance=1.05*mm;

// hotmount clamp screws distance from center
hotmount_clamp_thread = ThreadM3;
hotmount_clamp_nut = MHexNutM3;

hotmount_clamp_screw_dia = lookup(ThreadSize, hotmount_clamp_thread);
hotmount_clamp_screws_dist = hotmount_d_h[1][1] + 2*hotmount_clamp_screw_dia;
hotmount_clamp_pad = 2.5*mm;
hotmount_clamp_thickness = 5*mm;
hotmount_clamp_y = 2*(hotmount_clamp_screws_dist + hotmount_clamp_screw_dia + hotmount_clamp_pad);
hotmount_clamp_height = hotmount_d_h[1][1];

// length of the guidler bearing bolt/screw
guidler_bolt_h=10*mm;

guidler_mount_w=guidler_bearing[2];
guidler_mount_d=9*mm;

guidler_w=max(guidler_mount_w+7, guidler_bearing[2]*2.8);
guidler_d=5;
guidler_h=12;
guidler_extra_h_up=guidler_bearing[1]/2+hotmount_clamp_screw_dia/2;

guidler_mount_off_d=-guidler_bearing[1]/1.7;
guidler_mount_off_h=-guidler_bearing[1]/1.7;

extruder_guidler_mount_off_y = guidler_mount_off_d - guidler_bearing[1]/2;

house_inner_w=max(guidler_w+3, filament_d*2 + 4*2);

guidler_screws_thread = ThreadM3;
guidler_screws_thread_dia= lookup(ThreadSize, guidler_screws_thread);
guidler_screws_distance=6*mm;
guidler_screws_mount_d = 10*mm;
guidler_screws_mount_d_offset = 0*mm;

xcarriage_mount_hole_distance = 23*mm;
xcarriage_mount_w = xcarriage_mount_hole_distance + 6*mm;
xcarriage_mount_d = 6*mm;
xcarriage_mount_h = xcarriage_mount_w;

house_w = max(house_inner_w+2*house_bearing[2], hotmount_outer_size, xcarriage_mount_w);
house_d=house_bearing[1]/2+house_padding_wd;
house_h=house_bearing[1]+house_padding_h;

house_guidler_screw_h = guidler_screws_thread_dia+8*mm;
house_guidler_screw_h_offset = house_h/2 + guidler_screws_thread_dia + 4*mm;

CustomNema17 = dict_replace_multiple(Nema17,
        [
        [NemaFrontAxleLength, 22*mm]
        ]);
extruder_motor = CustomNema17;

// 80t + 20t w/228-2GT-6 belt
gears_distance=38.8*mm;
motor_offset_x = -8*mm;
motor_offset_y = 20*mm;
motor_offset_z = pythag_leg(motor_offset_y,gears_distance);

alpha = 0.7;
/*alpha = 1;*/
color_xcarriage = [0.3,0.8,0.3, alpha];
color_hotend = [0.8,0.4,0.4, alpha];
color_extruder = [0.2,0.6,0.9, alpha];
color_guidler = [0.4,0.5,0.8, alpha];

extruder_guidler_roll = 45;

house_offset_xcarriage_y = house_d+19*mm;
house_offset_xcarriage_z = -25;

// extruder connection point for guidler
extruder_conn_guidler = [ [0, extruder_guidler_mount_off_y, guidler_mount_off_h],  [1,0,0]];
extruder_conn_hotend = [[0,0,-house_h/2+hotmount_h_offset-0.1],[0,0,1]];
extruder_conn_xcarriage=[[0, house_offset_xcarriage_y, house_offset_xcarriage_z],[0,1,0]];
/*extruder_conn_xcarriage=[[house_w/2+10, 15,-36],[-1,0,0]];*/

extruder_conn_hotmount_clamp=[[house_w/2*(hotmount_clamp_side), 0,-house_h/2+hotmount_h_offset -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2], [0,0,0]];
hotmount_clamp_conn = [[0,0,0],[0,0,0]];

module extruder_guidler_mount(){

    translate([0,guidler_mount_off_d-guidler_bearing[1]/2, guidler_mount_off_h])
    {
        cubea([guidler_mount_w,guidler_mount_d,guidler_mount_d],align=[0,0,-1], extrasize=[0,5,0], extrasize_align=[0,1,0]);
        rotate([0,90,0])
        {
            fncylindera(d=guidler_mount_d, h=guidler_mount_w);
        }

        translate([0,0,-guidler_mount_d/2-1])
            cubea([house_w,guidler_mount_d,guidler_mount_d/2+1],align=[0,0,-1], extrasize=[0,5,0], extrasize_align=[0,1,0]);
    }
}

module extruder_own(show_filament=true)
{
    color(color_extruder)
    difference()
    {
        union(){

            hull()
            {
                // main house
                translate([0,bolt_center_offset,0])
                {
                    /*rotate([0,90,0])*/
                    /*fncylindera(h=house_w, d=house_d);*/
                    cubea(size=[house_w,house_d,house_h], align=[0,0,0]);
                }

                // hotend mount housing
                translate([0,0,-house_h/2 + hotmount_h_offset])
                {
                    /*cubea([house_w/2, hotmount_outer_size, hotend_mount_h], align=[-1,0,-1], extrasize=[guidler_mount_w/2,0,-hotmount_h_offset], extrasize_align=[1,-1,1]);*/
                    cubea([house_w, hotmount_outer_size, hotend_mount_h], align=[0,0,-1]);
                }

            }

            hull()
            {
                // main house
                translate([0,bolt_center_offset,0])
                {
                    /*rotate([0,90,0])*/
                    /*fncylindera(h=house_w, d=house_d);*/
                    cubea(size=[house_w, house_d, house_h], align=[0,0,0]);
                }

                // guidler screws mount
                translate([0, guidler_screws_mount_d_offset, house_guidler_screw_h_offset])
                {
                    cubea([house_w, guidler_screws_mount_d, house_guidler_screw_h], align=[0,0,0]);

                    for(i=[-1,1])
                    translate([i*(guidler_screws_distance), 0, 0])
                    rotate([0,90,90])
                    fncylindera(d=house_guidler_screw_h, h=guidler_screws_mount_d);
                }

                // mount onto xcarriage
                translate([0,0,0])
                    translate([0, house_offset_xcarriage_y, house_offset_xcarriage_z])
                    cubea([xcarriage_mount_w,xcarriage_mount_d,xcarriage_mount_h],[0,-1,0]);

                /*translate([0, house_offset_xcarriage_y, house_offset_xcarriage_z])*/
                /*cubea([xcarriage_mount_w,house_offset_xcarriage_y,xcarriage_mount_h],[0,-1,0]);*/
            }

            translate([0,bolt_center_offset,0])
            translate([motor_offset_x,motor_offset_y,motor_offset_z])
            {
                difference()
                {
                    slide_dist=4;
                    mount_thickness = motor_offset_x+house_w/2;
                    side = motorWidth(CustomNema17);

                    translate([-mount_thickness,0,0])
                        cubea([mount_thickness, side+slide_dist, side],[1,0,0]);

                    translate([-mount_thickness-1,0,0])
                        rotate([90,90,90])
                        linear_extrude(mount_thickness+2)
                        stepper_motor_mount(17, slide_distance=4, mochup=false);
                }
            }

            // guidler mount
            extruder_guidler_mount();
        }

        translate([0,bolt_center_offset,0])
        translate([motor_offset_x,motor_offset_y,motor_offset_z])
        {
            slide_dist=4;
            side = motorWidth(CustomNema17);
                mount_thickness = motor_offset_x+house_w/2;

            cubea([motorLength(CustomNema17), side+slide_dist, side],[1,0,0]);

            translate([-mount_thickness-1,0,0])
                rotate([90,90,90])
                linear_extrude(mount_thickness+2)
                stepper_motor_mount(17, slide_distance=4, mochup=false);
        }

        // guidler screws cutouts
        for(i=[-1,1])
        translate([i*(guidler_screws_distance), guidler_screws_mount_d_offset, house_guidler_screw_h_offset])
        {
            r= guidler_screws_thread_dia/2 * 1.1;
            cubea([r*2, guidler_screws_mount_d+1, r]);
            for(v=[-1,1])
            translate([0,0, v*r/2])
            {
                rotate([0,90,90])
                    fncylindera(r=r,h=guidler_screws_mount_d+1);
            }

            // guidler screw nuts drop-in slots
            translate([0,0, -r*2])
            cubea([nut_m3[1]*1.1,nut_m3[2]*1.25,house_guidler_screw_h], align=[0,0,1], extrasize=[0,0,1], extrasize_align=[0,0,1]);
        }

        // filament path ptfe line cutout
        fncylindera(d=filament_path_d, h=50, align=[0,0,0]);

        translate([0,0,-house_h/2+hotmount_h_offset])
        {
            hotmount_cutout(extend_cut=true);

            // clamp mount screw holes
            for(i=[-1,1])
            {
                translate([0, i*hotmount_clamp_screws_dist, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
                    rotate([0,90,0])
                    fncylindera(r=screw_m3[0], h=house_w+1);
            }

            translate([house_w/2 * (hotmount_clamp_side), 0, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
            {
                cubea([hotmount_clamp_thickness+0.2, hotmount_clamp_y+0.2, hotmount_clamp_height+0.2], align=[-hotmount_clamp_side,0,0], extrasize=[1,0,0], extrasize_align=[hotmount_clamp_side,0,0]);
            }
        }

        // cutout pivot to make sure guidler can rotate out
        guidler_pivot_r=pythag_hyp(abs(guidler_mount_off_d),abs(guidler_mount_off_h))+(guidler_bearing[1])/2;
        difference()
        {
            union()
            {
                /*translate([-house_inner_w/2,0,0])*/
                    /*translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])*/
                    /*rotate([0,90,0])*/
                    /*pie_slice(guidler_pivot_r*1.05, 120, 180, house_inner_w, $fn=50);*/

                translate([-house_inner_w/2,0,0])
                    translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])
                    rotate([0,90,0])
                    pie_slice(guidler_mount_d/2*1.25, 0, 180, house_inner_w/2 - guidler_mount_w/2, $fn=50);

                translate([guidler_mount_w/2,0,0])
                    translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])
                    rotate([0,90,0])
                    pie_slice(guidler_mount_d/2*1.25, 0, 180, house_inner_w/2 - guidler_mount_w/2, $fn=50);
            }

            extruder_guidler_mount();
        }

        // cutout inside main house for guidler
        guidler_pivot_r=pythag_hyp(guidler_mount_off_d,guidler_mount_off_h);
        translate([-house_inner_w/2,-guidler_bearing[1]/2, 0])
        {
            rotate([0,90,0])
            {
                pie_slice(r=guidler_bearing[1]/2*1.02, start_angle=0, end_angle=360, h=house_inner_w);
            }
        }

        /*translate([0,-guidler_bearing[1]/2,0])*/
        /*rotate([0,90,0])*/
        /*fncylindera(d=guidler_bearing[1]*1.05, h=house_inner_w);*/

        translate([0,bolt_center_offset,0])
        {
            // left bearing
            translate([-house_w/2-2*e,0,0])
                rotate([90,0,90])
                fncylindera(d=house_bearing[1]*1.02, h=house_bearing[2], align=[0,0,1]);

            // right bearing
            translate([house_w/2+2*e,0,0])
                rotate([90,0,90])
                fncylindera(d=house_bearing[1]*1.02, h=house_bearing[2], align=[0,0,-1]);

            // hobbed bolt
            rotate([90,0,90])
                fncylindera(d=8.5, h=house_w+1);
        }

        // guidler mount bolt hole
        translate([0,guidler_mount_off_d-guidler_bearing[1]/2, guidler_mount_off_h])
            rotate([0,90,0])
            fncylindera(r=screw_m3[0],h=guidler_w+1);
    }

    if(show_filament)
    {
        // filament
        fncylindera(d=filament_d, h=50);
    }

    /*translate([0,0,-house_h/2])*/
}

module hotmount_cutout(extend_cut=false)
{
    // cutout of j-head/e3d heatsink mount
    heights=vec_i(hotmount_d_h,1);
    for(e=v_itrlen(hotmount_d_h))
    {
        hs=v_sum(heights,e-1);
        translate([0,0,-hs])
        {
            d=hotmount_d_h[e][0]*hotmount_tolerance;
            h=hotmount_d_h[e][1]*hotmount_tolerance;
            fncylindera(d=d,h=h,align=[0,0,-1]);
            if(extend_cut)
            {
                cubea([house_w/2+1,d,h],align=[hotmount_clamp_side,0,-1]);
            }
        }
    }
}

module hotmount_clamp()
{
    difference()
    {
        union()
        {
            translate([house_w/2 * hotmount_clamp_side, 0, 0]);
            {
                cubea([hotmount_clamp_thickness, hotmount_clamp_y, hotmount_clamp_height], align=[-hotmount_clamp_side,0,0]);
            }

            difference()
            {
                translate([house_w/2 * hotmount_clamp_side, 0, 0]);
                {
                    cubea([house_w/2, hotmount_d_h[1][0], hotmount_clamp_height], align=[-hotmount_clamp_side,0,0]);
                }

                translate([(-house_w/2 * hotmount_clamp_side) + (-0.5*hotmount_clamp_side), 0, hotmount_d_h[0][1]+hotmount_d_h[1][1]/2])
                {
                    hotmount_cutout(extend_cut = false);
                }
            }

        }

        // clamp mount screw holes
        for(i=[-1,1])
        {
            translate([0, i*hotmount_clamp_screws_dist, 0])
                rotate([0,90,0])
                fncylindera(r=screw_m3[0], h=hotmount_clamp_thickness, align=[0,0,-hotmount_clamp_side], extra_h=1);
        }
    }
}

// guidler connection point
guidler_conn = [ [0, guidler_mount_off_d, guidler_mount_off_h],  [1,0,0]];

module guidler()
{
    // everything inside this module is relative to the center of the
    // bearing (that clamps the filament)
    color(color_guidler)
    difference()
    {
        union()
        {

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, 0])
                    cubea([guidler_w, guidler_d, guidler_h], align=[0,1,0]);

                // guidler bearing bolt holder
                rotate([0,90,0])
                    fncylindera(d=guidler_bearing[0]*1.5,h=guidler_w);
            }
            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, 0])
                    cubea([guidler_w, guidler_d, guidler_h], align=[0,1,0], extrasize=[0,0,guidler_extra_h_up], extrasize_align=[0,0,1]);

                // guidler mount point
                translate([0,guidler_mount_off_d, guidler_mount_off_h])
                    rotate([0,90,0])
                    fncylindera(d=guidler_mount_d,h=guidler_w);
            }

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, guidler_h])
                    cubea([guidler_w, guidler_d, 1], align=[0,1,0]);

                // guidler screws mount
                for(i=[-1,1])
                translate([i*(guidler_screws_distance),guidler_mount_off_d-guidler_mount_d/2, house_guidler_screw_h_offset])
                rotate([0,90,90])
                fncylindera(r=guidler_screws_thread_dia/2*3,h=guidler_d, align=[0,0,1]);

            }
        }

        // cutouts for clamping screws
        for(i=[-1,1])
        translate([i*(guidler_screws_distance),guidler_mount_off_d-guidler_mount_d/2, house_guidler_screw_h_offset])
        {
            r= guidler_screws_thread_dia/2*1.1;
            cubea([r*2,house_w+1,r]);
            for(v=[-1,1])
                translate([0,0, v*r/2])
                {
                    rotate([0,90,90])
                        fncylindera(r=r,h=house_w+1);
                }
        }

        // port hole to see bearing
        translate([0,-guidler_bearing[1]/2,0])
            cubea([guidler_bearing[0]*1.1, 100, guidler_bearing[1]/2], align=[0,0,1]);

        // cutout middle mount point pivot
        translate([0,guidler_mount_off_d, guidler_mount_off_h])
            rotate([0,90,0])
            {
                fncylindera(d=guidler_mount_d*1.25,h=guidler_mount_w*1.1);
            }

        // mount bolt hole
        translate([0,guidler_mount_off_d, guidler_mount_off_h])
            rotate([0,90,0])
            fncylindera(r=screw_m3[0],h=100);

        // guidler bearing bolt holder cutout
        union() {
            cubea([guidler_bolt_h*1.05+2*e,guidler_bearing[0]*1.05,guidler_bearing[0]*1.05],align=[0,1,0]);

            rotate([0,90,0])
                fncylindera(d=guidler_bearing[0]*1.05, h=guidler_bolt_h*1.05);
        }

        // guidler bearing cutout
        rotate([0,90,0])
            fncylindera(d=guidler_bearing[1]*1.1, h=guidler_bearing[2]*1.1);
    }

    %if(show_extras)
    {
        rotate([0,90,0])
        {
            fncylindera(d=guidler_bearing[1], h=guidler_bearing[2]);
            fncylindera(d=guidler_bearing[0], h=guidler_bolt_h);
        }
    }
}

module extras()
{
    hob_offset_x = -5*mm;

    // hobbed bolt
    // measurements from
    // http://wiki.e3d-online.com/wiki/E3D_HobbGoblin_Drawings
    hob_l = 64.5*mm;

    // center of the hob (from left side)
    hob_center = 37*mm;

    hob_conn_extruder=[[-hob_l/2+hob_center,0,0], [0,0,0]];

    attach([[0,bolt_center_offset,0],[0,0,0]], hob_conn_extruder)
    {
        /*connector(hob_conn_extruder);*/

        // hob-goblin hobbed bolt
        union()
        {
            thread_left = 20.5;
            thread_right = 14;
            hob_width = 4.2;
            color([0.1,0.2,0.3])
                translate([-hob_l/2,0,0])
                rotate([0,90,0])
                fncylindera(h=thread_left, d=8, align=[0,0,1]);

            color([0.6,0.6,0.6])
            difference()
            {
                translate([-hob_l/2+thread_left,0,0])
                    rotate([0,90,0])
                    fncylindera(h=hob_l-thread_left-thread_right, d=8, align=[0,0,1]);

                translate([-hob_l/2+hob_center,0,0])
                    rotate([0,90,0])
                    fncylindera(h=hob_width, d=8.1);
            }
            color([0.6,0.2,0.3])
                translate([-hob_l/2+hob_center,0,0])
                rotate([0,90,0])
                fncylindera(h=hob_width, d=7);

            color([0.1,0.2,0.3])
            translate([hob_l/2-thread_right,0,0])
                rotate([0,90,0])
                fncylindera(h=thread_right, d=8, align=[0,0,1]);

            /*rotate([0,90,0])*/
                /*fncylindera(h=hob_l, d=8);*/

            /*translate([-hob_l/2+hob_center,0,0])*/
                /*rotate([0,90,0])*/
                /*fncylindera(h=hob_width, d=8.1);*/

        }

        hob_conn_cog = [[-hob_l/2 + 13*mm,0,0], [-1,0,0]];

        /*connector(hob_conn_cog);*/
        // gear/cog
        // attach onto hobbed bolt
        cog_conn = [[11*mm,0,0],[1,0,0]];
        attach(hob_conn_cog, cog_conn, 019)
        {
            rotate([270,0,90])
                import("stl/gt2_extruder_cog_80tooth.stl");
        }
    }

    // motor/belt
    translate([0,bolt_center_offset,0])
    translate([motor_offset_x-1,motor_offset_y,motor_offset_z])
    {
        // main motor body
        motor(extruder_motor, NemaShort, dualAxis=false, orientation=[0,90,0]);

        translate([-1,0,0])
            rotate([0,0,180])
            import("stl/GT2_20tooth.stl");
    }

    // hotend
    hotend_conn =[[0,0,21.35*mm],[0,0,1]];
    attach(extruder_conn_hotend, hotend_conn)
        color(color_hotend)
        rotate([90,0,270])
        import("stl/E3D_V6_1.75mm_Universal_HotEnd_Mockup.stl");

    // x carriage
    xcarriage_conn =[[-0.4,-8.5,-1],[0,-1,0]];
    attach(extruder_conn_xcarriage, xcarriage_conn)
    {
        /*connector(xcarriage_conn);*/
        color(color_xcarriage)
            translate([282*mm,-170,14])
            rotate([90,180,180])
            import("../wilson/x-carriage.stl");
    }
}

module extruder()
{
    extruder_own();

    attach(extruder_conn_guidler, guidler_conn, extruder_guidler_roll)
    {
        guidler(show_extras=true);
    }

    attach(extruder_conn_hotmount_clamp, hotmount_clamp_conn)
    {
        /*connector(hotmount_clamp_conn);*/
        hotmount_clamp(); }

    if(true) { extras(); } }

module print() { extruder_conn_layflat = [[-house_w/2,0,0],[-1,0,0]];
attach([[0,0,0],[0,0,-1]], extruder_conn_layflat) {
        /*connector(extruder_conn_layflat);*/
        extruder_own(false,false); }

    guidler_conn_layflat = [ [0, guidler_mount_off_d-guidler_mount_d/2,
    guidler_mount_off_h],  [0,-1,0]]; attach([[34*mm,10*mm,0],[0,0,-1]],
    guidler_conn_layflat) {
        /*connector(guidler_conn_layflat);*/
        guidler(false); }

    hotmount_clamp_conn_layflat=[[0,0,0],[-1,0,0]];
    attach([[54*mm,0,0],[0,0,1]], hotmount_clamp_conn_layflat) {
        /*connector(hotmount_clamp_conn);*/
        hotmount_clamp(); } }

/*extruder();*/
/*print();*/

include <thing_libutils/metric-thread.scad>;
include <thing_libutils/metric-hexnut.scad>;
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/attach.scad>;
include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>

module capmount(show_sensor=false,lower_height=12,mount_lower=12,height=10,thickness=5,screws_spacing=21,screw_offset=[1,0],screws_diameter=4,sensor_spacing=3,sensor_height=[15,40,5],sensor_diameter=12)

{
    mount_start = 1.7+sensor_spacing+screws_spacing+screws_diameter+2*screw_offset[0];
    if(show_sensor)
    {
        translate([-8+sensor_diameter/2+thickness,-.5+mount_start+thickness+sensor_diameter/2,-39])
        {
            translate([0,0,sensor_height[1]+sensor_height[2]])
                fncylindera(d=sensor_diameter-0.5,h=sensor_height[0]);
            translate([0,0,sensor_height[2]])
                %fncylindera(d=sensor_diameter-0.5,h=sensor_height[1]);
            fncylindera(d=sensor_diameter-0.5,h=sensor_height[2]);
        }
    }

    //  Mount
    $fn=50;
    difference() {
        translate([0,0,-lower_height])
            cube([thickness+1, mount_start, height+lower_height]);

        //Screws 1
        translate([2*e, 4+screw_offset[0], height/2+screw_offset[1]])
        {
            rotate([0,90,0])
            {
                fncylindera(d=screws_diameter, h=thickness+1);
                translate([0,0,2.5])
                    fncylindera(h = 4, d=8.2, $fn=6);
            }
            //Screws 2
            translate([0,screws_spacing,0])
                rotate([0,90,0])
                {
                    fncylindera(d=screws_diameter, h=thickness+1);
                    translate([0,0,2.5])
                        fncylindera(h = 4, d=8.2, $fn=6);
                }
        }

    }
    //Sensor mount
    $fn=200;
    translate([-8,-.3,0])
        difference() {
            union() {
                translate([sensor_diameter/2+thickness,mount_start+thickness+sensor_diameter/2, -lower_height])
                    fncylindera(d=sensor_diameter+2*thickness, h=height+lower_height-mount_lower);

            }
            translate([sensor_diameter/2+thickness,mount_start+thickness+sensor_diameter/2, -height/2])
                fncylindera(d=sensor_diameter+0,5, h=2*height, center=true);

            cutoff=[1,2];
            translate([0,mount_start, -lower_height-e])
                cubea([cutoff[0],sensor_diameter+thickness*2,height+lower_height-mount_lower+2*e],[1,1,1]);

            translate([sensor_diameter+thickness*2,mount_start, -lower_height-e])
                cubea([cutoff[1],sensor_diameter+thickness*2,height+lower_height-mount_lower+2*e],[-1,1,1]);
        }
}

house_bearing=bearing_MR128;
guidler_bearing=bearing_625;

house_padding_wd=11*mm;
house_padding_h=4*mm;

filapath_width=10*mm;

// 4mm ptfe tube
filament_path_d = 4*mm;

// offset from the center of the bolt to the filament path
bolt_center_offset = 4.2*mm;

hotend_mount_h=10.5*mm;

// from E3D V6 heatsink drawing
// http://wiki.e3d-online.com/wiki/File:DRAWING-V6-175-SINK.png
// each entry == dia + h
hotmount_d_h=[[16*mm,3.7*mm],[12*mm,6*mm],[16*mm,3*mm]];
hotmount_outer_size=max(vec_i(hotmount_d_h,0))+10*mm;
hotmount_h_offset=-2*mm;
// which side does hotend slide in (x-axis, i.e. -1 is left, 1 is right)
hotmount_clamp_side=1*mm;

hotmount_tolerance=1.05*mm;

// hotmount clamp screws distance from center
hotmount_clamp_thread = ThreadM3;
hotmount_clamp_nut = MHexNutM3;

hotmount_clamp_screw_dia = lookup(ThreadSize, hotmount_clamp_thread);
hotmount_clamp_screws_dist = hotmount_d_h[1][1] + 2*hotmount_clamp_screw_dia;
hotmount_clamp_pad = 2.5*mm;
hotmount_clamp_thickness = 5*mm;
hotmount_clamp_y = 2*(hotmount_clamp_screws_dist + hotmount_clamp_screw_dia + hotmount_clamp_pad);
hotmount_clamp_height = hotmount_d_h[1][1];

// length of the guidler bearing bolt/screw
guidler_bolt_h=10*mm;

guidler_mount_w=guidler_bearing[2];
guidler_mount_d=9*mm;

guidler_w=max(guidler_mount_w+7, guidler_bearing[2]*2.8);
guidler_d=5;
guidler_h=12;
guidler_extra_h_up=guidler_bearing[1]/2+hotmount_clamp_screw_dia/2;

guidler_mount_off_d=-guidler_bearing[1]/1.7;
guidler_mount_off_h=-guidler_bearing[1]/1.7;

extruder_guidler_mount_off_y = guidler_mount_off_d - guidler_bearing[1]/2;

house_inner_w=max(guidler_w+3, filament_d*2 + 4*2);

guidler_screws_thread = ThreadM3;
guidler_screws_thread_dia= lookup(ThreadSize, guidler_screws_thread);
guidler_screws_distance=6*mm;
guidler_screws_mount_d = 10*mm;
guidler_screws_mount_d_offset = 0*mm;

xcarriage_mount_hole_distance = 23*mm;
xcarriage_mount_w = xcarriage_mount_hole_distance + 6*mm;
xcarriage_mount_d = 6*mm;
xcarriage_mount_h = xcarriage_mount_w;

house_w = max(house_inner_w+2*house_bearing[2], hotmount_outer_size, xcarriage_mount_w);
house_d=house_bearing[1]/2+house_padding_wd;
house_h=house_bearing[1]+house_padding_h;

house_guidler_screw_h = guidler_screws_thread_dia+8*mm;
house_guidler_screw_h_offset = house_h/2 + guidler_screws_thread_dia + 4*mm;

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

// 80t + 20t w/228-2GT-6 belt
gears_distance=38.8*mm;
motor_offset_x = -8*mm;
motor_offset_y = 20*mm;
motor_offset_z = pythag_leg(motor_offset_y,gears_distance);

alpha = 0.7;
/*alpha = 1;*/
color_xcarriage = [0.3,0.8,0.3, alpha];
color_hotend = [0.8,0.4,0.4, alpha];
color_extruder = [0.2,0.6,0.9, alpha];
color_guidler = [0.4,0.5,0.8, alpha];

extruder_guidler_roll = 45;

house_offset_xcarriage_y = house_d+19*mm;
house_offset_xcarriage_z = -25;

// extruder connection point for guidler
extruder_conn_guidler = [ [0, extruder_guidler_mount_off_y, guidler_mount_off_h],  [1,0,0]];
extruder_conn_hotend = [[0,0,-house_h/2+hotmount_h_offset-0.1],[0,0,1]];
extruder_conn_xcarriage=[[0, house_offset_xcarriage_y, house_offset_xcarriage_z],[0,1,0]];
/*extruder_conn_xcarriage=[[house_w/2+10, 15,-36],[-1,0,0]];*/

extruder_conn_hotmount_clamp=[[house_w/2*(hotmount_clamp_side), 0,-house_h/2+hotmount_h_offset -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2], [0,0,0]];
hotmount_clamp_conn = [[0,0,0],[0,0,0]];

module extruder_guidler_mount(){

    translate([0,guidler_mount_off_d-guidler_bearing[1]/2, guidler_mount_off_h])
    {
        cubea([guidler_mount_w,guidler_mount_d,guidler_mount_d],align=[0,0,-1], extrasize=[0,5,0], extrasize_align=[0,1,0]);
        rotate([0,90,0])
        {
            fncylindera(d=guidler_mount_d, h=guidler_mount_w);
        }

        translate([0,0,-guidler_mount_d/2-1])
            cubea([house_w,guidler_mount_d,guidler_mount_d/2+1],align=[0,0,-1], extrasize=[0,5,0], extrasize_align=[0,1,0]);
    }
}

module extruder_own(show_filament=true)
{
    color(color_extruder)
    difference()
    {
        union(){

            hull()
            {
                // main house
                translate([0,bolt_center_offset,0])
                {
                    /*rotate([0,90,0])*/
                    /*fncylindera(h=house_w, d=house_d);*/
                    cubea(size=[house_w,house_d,house_h], align=[0,0,0]);
                }

                // hotend mount housing
                translate([0,0,-house_h/2 + hotmount_h_offset])
                {
                    /*cubea([house_w/2, hotmount_outer_size, hotend_mount_h], align=[-1,0,-1], extrasize=[guidler_mount_w/2,0,-hotmount_h_offset], extrasize_align=[1,-1,1]);*/
                    cubea([house_w, hotmount_outer_size, hotend_mount_h], align=[0,0,-1]);
                }

            }

            hull()
            {
                // main house
                translate([0,bolt_center_offset,0])
                {
                    /*rotate([0,90,0])*/
                    /*fncylindera(h=house_w, d=house_d);*/
                    cubea(size=[house_w, house_d, house_h], align=[0,0,0]);
                }

                // guidler screws mount
                translate([0, guidler_screws_mount_d_offset, house_guidler_screw_h_offset])
                {
                    cubea([house_w, guidler_screws_mount_d, house_guidler_screw_h], align=[0,0,0]);

                    for(i=[-1,1])
                    translate([i*(guidler_screws_distance), 0, 0])
                    rotate([0,90,90])
                    fncylindera(d=house_guidler_screw_h, h=guidler_screws_mount_d);
                }

                // mount onto xcarriage
                translate([0,0,0])
                    translate([0, house_offset_xcarriage_y, house_offset_xcarriage_z])
                    cubea([xcarriage_mount_w,xcarriage_mount_d,xcarriage_mount_h],[0,-1,0]);

                /*translate([0, house_offset_xcarriage_y, house_offset_xcarriage_z])*/
                /*cubea([xcarriage_mount_w,house_offset_xcarriage_y,xcarriage_mount_h],[0,-1,0]);*/
            }

            translate([0,bolt_center_offset,0])
            translate([motor_offset_x,motor_offset_y,motor_offset_z])
            {
                difference()
                {
                    slide_dist=4;
                    mount_thickness = motor_offset_x+house_w/2;
                    side = motorWidth(CustomNema17);

                    translate([-mount_thickness,0,0])
                        cubea([mount_thickness, side+slide_dist, side],[1,0,0]);

                    translate([-mount_thickness-1,0,0])
                        rotate([90,90,90])
                        linear_extrude(mount_thickness+2)
                        stepper_motor_mount(17, slide_distance=4, mochup=false);
                }
            }

            // guidler mount
            extruder_guidler_mount();
        }

        translate([0,bolt_center_offset,0])
        translate([motor_offset_x,motor_offset_y,motor_offset_z])
        {
            slide_dist=4;
            side = motorWidth(CustomNema17);
                mount_thickness = motor_offset_x+house_w/2;

            cubea([motorLength(CustomNema17), side+slide_dist, side],[1,0,0]);

            translate([-mount_thickness-1,0,0])
                rotate([90,90,90])
                linear_extrude(mount_thickness+2)
                stepper_motor_mount(17, slide_distance=4, mochup=false);
        }

        // guidler screws cutouts
        for(i=[-1,1])
        translate([i*(guidler_screws_distance), guidler_screws_mount_d_offset, house_guidler_screw_h_offset])
        {
            r= guidler_screws_thread_dia/2 * 1.1;
            cubea([r*2, guidler_screws_mount_d+1, r]);
            for(v=[-1,1])
            translate([0,0, v*r/2])
            {
                rotate([0,90,90])
                    fncylindera(r=r,h=guidler_screws_mount_d+1);
            }

            // guidler screw nuts drop-in slots
            translate([0,0, -r*2])
            cubea([nut_m3[1]*1.1,nut_m3[2]*1.25,house_guidler_screw_h], align=[0,0,1], extrasize=[0,0,1], extrasize_align=[0,0,1]);
        }

        // filament path ptfe line cutout
        fncylindera(d=filament_path_d, h=50, align=[0,0,0]);

        translate([0,0,-house_h/2+hotmount_h_offset])
        {
            hotmount_cutout(extend_cut=true);

            // clamp mount screw holes
            for(i=[-1,1])
            {
                translate([0, i*hotmount_clamp_screws_dist, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
                    rotate([0,90,0])
                    fncylindera(r=screw_m3[0], h=house_w+1);
            }

            translate([house_w/2 * (hotmount_clamp_side), 0, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
            {
                cubea([hotmount_clamp_thickness+0.2, hotmount_clamp_y+0.2, hotmount_clamp_height+0.2], align=[-hotmount_clamp_side,0,0], extrasize=[1,0,0], extrasize_align=[hotmount_clamp_side,0,0]);
            }
        }

        // cutout pivot to make sure guidler can rotate out
        guidler_pivot_r=pythag_hyp(abs(guidler_mount_off_d),abs(guidler_mount_off_h))+(guidler_bearing[1])/2;
        difference()
        {
            union()
            {
                /*translate([-house_inner_w/2,0,0])*/
                    /*translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])*/
                    /*rotate([0,90,0])*/
                    /*pie_slice(guidler_pivot_r*1.05, 120, 180, house_inner_w, $fn=50);*/

                translate([-house_inner_w/2,0,0])
                    translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])
                    rotate([0,90,0])
                    pie_slice(guidler_mount_d/2*1.25, 0, 180, house_inner_w/2 - guidler_mount_w/2, $fn=50);

                translate([guidler_mount_w/2,0,0])
                    translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])
                    rotate([0,90,0])
                    pie_slice(guidler_mount_d/2*1.25, 0, 180, house_inner_w/2 - guidler_mount_w/2, $fn=50);
            }

            extruder_guidler_mount();
        }

        // cutout inside main house for guidler
        guidler_pivot_r=pythag_hyp(guidler_mount_off_d,guidler_mount_off_h);
        translate([-house_inner_w/2,-guidler_bearing[1]/2, 0])
        {
            rotate([0,90,0])
            {
                pie_slice(r=guidler_bearing[1]/2*1.02, start_angle=0, end_angle=360, h=house_inner_w);
            }
        }

        /*translate([0,-guidler_bearing[1]/2,0])*/
        /*rotate([0,90,0])*/
        /*fncylindera(d=guidler_bearing[1]*1.05, h=house_inner_w);*/

        translate([0,bolt_center_offset,0])
        {
            // left bearing
            translate([-house_w/2-2*e,0,0])
                rotate([90,0,90])
                fncylindera(d=house_bearing[1]*1.02, h=house_bearing[2], align=[0,0,1]);

            // right bearing
            translate([house_w/2+2*e,0,0])
                rotate([90,0,90])
                fncylindera(d=house_bearing[1]*1.02, h=house_bearing[2], align=[0,0,-1]);

            // hobbed bolt
            rotate([90,0,90])
                fncylindera(d=8.5, h=house_w+1);
        }

        // guidler mount bolt hole
        translate([0,guidler_mount_off_d-guidler_bearing[1]/2, guidler_mount_off_h])
            rotate([0,90,0])
            fncylindera(r=screw_m3[0],h=guidler_w+1);
    }

    if(show_filament)
    {
        // filament
        fncylindera(d=filament_d, h=50);
    }

    /*translate([0,0,-house_h/2])*/
}

module hotmount_cutout(extend_cut=false)
{
    // cutout of j-head/e3d heatsink mount
    heights=vec_i(hotmount_d_h,1);
    for(e=v_itrlen(hotmount_d_h))
    {
        hs=v_sum(heights,e-1);
        translate([0,0,-hs])
        {
            d=hotmount_d_h[e][0]*hotmount_tolerance;
            h=hotmount_d_h[e][1]*hotmount_tolerance;
            fncylindera(d=d,h=h,align=[0,0,-1]);
            if(extend_cut)
            {
                cubea([house_w/2+1,d,h],align=[hotmount_clamp_side,0,-1]);
            }
        }
    }
}

module hotmount_clamp()
{
    difference()
    {
        union()
        {
            translate([house_w/2 * hotmount_clamp_side, 0, 0]);
            {
                cubea([hotmount_clamp_thickness, hotmount_clamp_y, hotmount_clamp_height], align=[-hotmount_clamp_side,0,0]);
            }

            difference()
            {
                translate([house_w/2 * hotmount_clamp_side, 0, 0]);
                {
                    cubea([house_w/2, hotmount_d_h[1][0], hotmount_clamp_height], align=[-hotmount_clamp_side,0,0]);
                }

                translate([(-house_w/2 * hotmount_clamp_side) + (-0.5*hotmount_clamp_side), 0, hotmount_d_h[0][1]+hotmount_d_h[1][1]/2])
                {
                    hotmount_cutout(extend_cut = false);
                }
            }

        }

        // clamp mount screw holes
        for(i=[-1,1])
        {
            translate([0, i*hotmount_clamp_screws_dist, 0])
                rotate([0,90,0])
                fncylindera(r=screw_m3[0], h=hotmount_clamp_thickness, align=[0,0,-hotmount_clamp_side], extra_h=1);
        }
    }
}

// guidler connection point
guidler_conn = [ [0, guidler_mount_off_d, guidler_mount_off_h],  [1,0,0]];

module guidler()
{
    // everything inside this module is relative to the center of the
    // bearing (that clamps the filament)
    color(color_guidler)
    difference()
    {
        union()
        {

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, 0])
                    cubea([guidler_w, guidler_d, guidler_h], align=[0,1,0]);

                // guidler bearing bolt holder
                rotate([0,90,0])
                    fncylindera(d=guidler_bearing[0]*1.5,h=guidler_w);
            }
            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, 0])
                    cubea([guidler_w, guidler_d, guidler_h], align=[0,1,0], extrasize=[0,0,guidler_extra_h_up], extrasize_align=[0,0,1]);

                // guidler mount point
                translate([0,guidler_mount_off_d, guidler_mount_off_h])
                    rotate([0,90,0])
                    fncylindera(d=guidler_mount_d,h=guidler_w);
            }

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, guidler_h])
                    cubea([guidler_w, guidler_d, 1], align=[0,1,0]);

                // guidler screws mount
                for(i=[-1,1])
                translate([i*(guidler_screws_distance),guidler_mount_off_d-guidler_mount_d/2, house_guidler_screw_h_offset])
                rotate([0,90,90])
                fncylindera(r=guidler_screws_thread_dia/2*3,h=guidler_d, align=[0,0,1]);

            }
        }

        // cutouts for clamping screws
        for(i=[-1,1])
        translate([i*(guidler_screws_distance),guidler_mount_off_d-guidler_mount_d/2, house_guidler_screw_h_offset])
        {
            r= guidler_screws_thread_dia/2*1.1;
            cubea([r*2,house_w+1,r]);
            for(v=[-1,1])
                translate([0,0, v*r/2])
                {
                    rotate([0,90,90])
                        fncylindera(r=r,h=house_w+1);
                }
        }

        // port hole to see bearing
        translate([0,-guidler_bearing[1]/2,0])
            cubea([guidler_bearing[0]*1.1, 100, guidler_bearing[1]/2], align=[0,0,1]);

        // cutout middle mount point pivot
        translate([0,guidler_mount_off_d, guidler_mount_off_h])
            rotate([0,90,0])
            {
                fncylindera(d=guidler_mount_d*1.25,h=guidler_mount_w*1.1);
            }

        // mount bolt hole
        translate([0,guidler_mount_off_d, guidler_mount_off_h])
            rotate([0,90,0])
            fncylindera(r=screw_m3[0],h=100);

        // guidler bearing bolt holder cutout
        union() {
            cubea([guidler_bolt_h*1.05+2*e,guidler_bearing[0]*1.05,guidler_bearing[0]*1.05],align=[0,1,0]);

            rotate([0,90,0])
                fncylindera(d=guidler_bearing[0]*1.05, h=guidler_bolt_h*1.05);
        }

        // guidler bearing cutout
        rotate([0,90,0])
            fncylindera(d=guidler_bearing[1]*1.1, h=guidler_bearing[2]*1.1);
    }

    %if(show_extras)
    {
        rotate([0,90,0])
        {
            fncylindera(d=guidler_bearing[1], h=guidler_bearing[2]);
            fncylindera(d=guidler_bearing[0], h=guidler_bolt_h);
        }
    }
}

module extras()
{
    hob_offset_x = -5*mm;

    // hobbed bolt
    // measurements from
    // http://wiki.e3d-online.com/wiki/E3D_HobbGoblin_Drawings
    hob_l = 64.5*mm;

    // center of the hob (from left side)
    hob_center = 37*mm;

    hob_conn_extruder=[[-hob_l/2+hob_center,0,0], [0,0,0]];

    attach([[0,bolt_center_offset,0],[0,0,0]], hob_conn_extruder)
    {
        /*connector(hob_conn_extruder);*/

        // hob-goblin hobbed bolt
        union()
        {
            thread_left = 20.5;
            thread_right = 14;
            hob_width = 4.2;
            color([0.1,0.2,0.3])
                translate([-hob_l/2,0,0])
                rotate([0,90,0])
                fncylindera(h=thread_left, d=8, align=[0,0,1]);

            color([0.6,0.6,0.6])
            difference()
            {
                translate([-hob_l/2+thread_left,0,0])
                    rotate([0,90,0])
                    fncylindera(h=hob_l-thread_left-thread_right, d=8, align=[0,0,1]);

                translate([-hob_l/2+hob_center,0,0])
                    rotate([0,90,0])
                    fncylindera(h=hob_width, d=8.1);
            }
            color([0.6,0.2,0.3])
                translate([-hob_l/2+hob_center,0,0])
                rotate([0,90,0])
                fncylindera(h=hob_width, d=7);

            color([0.1,0.2,0.3])
            translate([hob_l/2-thread_right,0,0])
                rotate([0,90,0])
                fncylindera(h=thread_right, d=8, align=[0,0,1]);

            /*rotate([0,90,0])*/
                /*fncylindera(h=hob_l, d=8);*/

            /*translate([-hob_l/2+hob_center,0,0])*/
                /*rotate([0,90,0])*/
                /*fncylindera(h=hob_width, d=8.1);*/

        }

        hob_conn_cog = [[-hob_l/2 + 13*mm,0,0], [-1,0,0]];

        /*connector(hob_conn_cog);*/
        // gear/cog
        // attach onto hobbed bolt
        cog_conn = [[11*mm,0,0],[1,0,0]];
        attach(hob_conn_cog, cog_conn, 019)
        {
            rotate([270,0,90])
                import("stl/gt2_extruder_cog_80tooth.stl");
        }
    }

    // motor/belt
    translate([0,bolt_center_offset,0])
    translate([motor_offset_x-1,motor_offset_y,motor_offset_z])
    {
        // main motor body
        motor(extruder_motor, NemaShort, dualAxis=false, orientation=[0,90,0]);

        translate([-1,0,0])
            rotate([0,0,180])
            import("stl/GT2_20tooth.stl");
    }

    // hotend
    hotend_conn =[[0,0,21.35*mm],[0,0,1]];
    attach(extruder_conn_hotend, hotend_conn)
        color(color_hotend)
        rotate([90,0,270])
        import("stl/E3D_V6_1.75mm_Universal_HotEnd_Mockup.stl");

    // x carriage
    xcarriage_conn =[[-0.4,-8.5,-1],[0,-1,0]];
    attach(extruder_conn_xcarriage, xcarriage_conn)
    {
        /*connector(xcarriage_conn);*/
        color(color_xcarriage)
            translate([282*mm,-170,14])
            rotate([90,180,180])
            import("../wilson/x-carriage.stl");
    }
}

module extruder()
{
    extruder_own();

    attach(extruder_conn_guidler, guidler_conn, extruder_guidler_roll)
    {
        guidler(show_extras=true);
    }

    attach(extruder_conn_hotmount_clamp, hotmount_clamp_conn)
    {
        /*connector(hotmount_clamp_conn);*/
        hotmount_clamp(); }

    if(true) { extras(); } }

module print() { extruder_conn_layflat = [[-house_w/2,0,0],[-1,0,0]];
attach([[0,0,0],[0,0,-1]], extruder_conn_layflat) {
        /*connector(extruder_conn_layflat);*/
        extruder_own(false,false); }

    guidler_conn_layflat = [ [0, guidler_mount_off_d-guidler_mount_d/2,
    guidler_mount_off_h],  [0,-1,0]]; attach([[34*mm,10*mm,0],[0,0,-1]],
    guidler_conn_layflat) {
        /*connector(guidler_conn_layflat);*/
        guidler(false); }

    hotmount_clamp_conn_layflat=[[0,0,0],[-1,0,0]];
    attach([[54*mm,0,0],[0,0,1]], hotmount_clamp_conn_layflat) {
        /*connector(hotmount_clamp_conn);*/
        hotmount_clamp(); } }

/*extruder();*/
/*print();*/


support plane reorganization

support plane reorganization

names=["John", "Jane"];

module rounded_surface_(size)
{
  r=size[2]/2;
  translate([0, 0, r])
    hull()
      for(dx=[r, size[0]-r])
        for(dy=[r, size[1]-r])
          translate([dx, dy, 0])
            sphere(r=r, $fn=r*10); // TODO: r*20!
}

module rounded_half_surface_(size)
{
  translate([0, 0, -size[2]/2])
    difference()
    {
      rounded_surface_(size);
      translate(size[2]/2*[0,0,-1])
        cube(size);
    }
}

corrners = [ [-1,-1,0], [-1,+1,0], [+1,-1,0], [+1,+1,0] ];

// wall-mounted part
module wall(size)
{
  hull()
    difference()
    {
      #for(t = corrners)
      {
        off = [size[0]/2*t[0], size[1]/2*t[1], 0*t[2]];
          translate(off)
            sphere(size[2]);
      };
      translate([0,0,-size[2]]) cube(2*size, center=true);
    }
}

// water drops catching plane
module plane(size)
{
  translate([0, 0, size[1]/2])
    rotate([90,0,0])
      hull()
        for(t = corrners)
        {
          off = [size[0]/2*t[0], size[1]/2*t[1], 0*t[2]];
            translate(off)
              sphere(size[2]);
        };
}

// element for holding a single brush
module holder(size)
{
  cube([size[0], 7, size[2]]);
  translate([1.5, 7, size[2]-3])
    rotate([-90,0,0])
    {
      cylinder(r=(8-1.5)/2, h=7+2);
      cylinder(r=(3-1)/2, h=14+2);
    }
}

module brush_holder()
{
  translate([0, -23.25, 0])
    rotate([90, 0, 0])
      rounded_surface_([36-2*2, 29, 2]);
  translate(1/2*[36, 50, 0]) // TODO: temporary
  {
  translate(-1/2*[36,50, 0])    // TODO: to be removed
    rounded_half_surface_([36, 50, 5]);

  for(dx=[-1, +1])
    translate([dx*20/2-1, -1, 2])
      holder([3,25,18]);
  }
}

brush_holder();

//rounded_surface_([20,30,5]);
//rounded_half_surface_([20,30,5]);

names=["John", "Jane"];

module rounded_surface_(size)
{
  r=size[2]/2;
  translate([0, 0, r])
    hull()
      for(dx=[r, size[0]-r])
        for(dy=[r, size[1]-r])
          translate([dx, dy, 0])
            sphere(r=r, $fn=30);
}

module rounded_half_surface_(size)
{
  translate([0, 0, -size[2]/2])
    difference()
    {
      rounded_surface_(size);
      translate(size[2]/2*[0,0,-1])
        cube(size);
    }
}

corrners = [ [-1,-1,0], [-1,+1,0], [+1,-1,0], [+1,+1,0] ];

// wall-mounted part
module wall(size)
{
  hull()
    difference()
    {
      #for(t = corrners)
      {
        off = [size[0]/2*t[0], size[1]/2*t[1], 0*t[2]];
          translate(off)
            sphere(size[2]);
      };
      translate([0,0,-size[2]]) cube(2*size, center=true);
    }
}

// water drops catching plane
module plane(tr, size)
{
  rotate([90,0,0])
    translate(tr)
      hull()
        for(t = corrners)
        {
          off = [size[0]/2*t[0], size[1]/2*t[1], 0*t[2]];
            translate(off)
              sphere(size[2]);
        };
}

// element for holding a single brush
module holder(size)
{
  cube([size[0], 7, size[2]]);
  translate([1.5, 7, size[2]-3])
    rotate([-90,0,0])
    {
      cylinder(r=(8-1.5)/2, h=7+2);
      cylinder(r=(3-1)/2, h=14+2);
    }
}

module brush_holder()
{
  wall([36,50,2]);
  plane([0,16.5,50/2-2], [36-2*2,29,2]);
  for(dx=[-1, +1])
    translate([dx*20/2-1, -1, 2])
      holder([3,25,18]);
}

brush_holder();

//rounded_surface_([20,30,5]);
//rounded_half_surface_([20,30,5]);


higher side wall + printing just 1 element at a time

w=119;
s=21;
h=2.5;

module wedge(width, span, height)
{
  polyhedron(
    points=[
             [0, 0, 0],
             [span, 0, 0],
             [span, width, 0],
             [0, width, 0],
             [0, width, height],
             [span, width, height],
           ],
    faces=[
            // bottom
            [0,1,2],
            [2,3,0],
            // sides
            [5,2,1],
            [0,3,4],
            // back
            [3,2,4],
            [5,4,2],
            // top
            [0,4,5],
            [5,1,0],
          ]
   );
};

module fence(width, height)
{
  cube([width, 119, height-h]);
  translate([0,0,1])
    wedge(width=w, span=1, height=h);
}

module support()
{
  translate([1,0,0])
  {
    difference()
    {
      union()
      {
        wedge(width=w, span=s, height=h);

        // rounded ending
        translate([s/2, w, 0])
          difference()
          {
            cylinder(r=s/2, h=h);
            translate([-s/2, -s/2*2, 0])
              cube([s, s, h]);
          }
      }

      // screw hole
      translate([s/2, w-8/2, 0])
        cylinder(r=8/2, h=h);
    }
  }

  // side walls
  for(i=[0, s+1])
    translate(i*[1,0,0])
      fence(width=1, height=h+2);
}

support(2.5);

w=119;
s=21;
h=2.5;

module wedge(width, span, height)
{
  polyhedron(
    points=[
             [0, 0, 0],
             [span, 0, 0],
             [span, width, 0],
             [0, width, 0],
             [0, width, height],
             [span, width, height],
           ],
    faces=[
            // bottom
            [0,1,2],
            [2,3,0],
            // sides
            [5,2,1],
            [0,3,4],
            // back
            [3,2,4],
            [5,4,2],
            // top
            [0,4,5],
            [5,1,0],
          ]
   );
};

module fence(width, height)
{
  cube([width, 119, height-h]);
  translate([0,0,1])
    wedge(width=w, span=1, height=h);
}

module support()
{
  translate([1,0,0])
  {
    difference()
    {
      union()
      {
        wedge(width=w, span=s, height=h);

        // rounded ending
        translate([s/2, w, 0])
          difference()
          {
            cylinder(r=s/2, h=h);
            translate([-s/2, -s/2*2, 0])
              cube([s, s, h]);
          }
      }

      // screw hole
      translate([s/2, w-8/2, 0])
        cylinder(r=8/2, h=h);
    }
  }

  // side walls
  for(i=[0, s+1])
    translate(i*[1,0,0])
      fence(width=1, height=h+1);
}

for(i=[0:2])
  translate(i*[25, 0, 0])
    support(2.5);


y-rod-clamp: fix print orientation

y-rod-clamp: fix print orientation

use <rod-clamps.scad>
include <rod-clamps.h>

include <config.scad>

module part_y_rod_clamp()
{
    mount_rod_clamp_full(rod_d=zaxis_rod_d, thick=4, width=extrusion_size, thread=extrusion_mount_thread, align=Z+X, orient=-Z);
}

use <rod-clamps.scad>
include <rod-clamps.h>

include <config.scad>

module part_y_rod_clamp()
{
    mount_rod_clamp_full(rod_d=zaxis_rod_d, thick=4, width=extrusion_size, thread=extrusion_mount_thread, align=Z+X, orient=-X);
}


Adding AssemblyJoint.scad

Adding AssemblyJoint.scad

timber_construct_w = 37;
timber_construct_h = 63;
base_sheet_t = 18;
d_hole = 5;

hyp = sqrt(((timber_construct_w/2)*(timber_construct_w/2))+((timber_construct_w/2)*(timber_construct_w/2)));
$fn=60;

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()
    {
        cube([timber_construct_w,d_hole,d_hole*3]);
        cube([d_hole,timber_construct_w,d_hole*3]);
      translate([d_hole,timber_construct_w/2+d_hole,0]) rotate([90,-90,90])  prism(d_hole*3,timber_construct_w/2,timber_construct_w/2);
    }
    translate([timber_construct_w*3/4, d_hole*2, d_hole*1.5]) rotate([90,0,0]) cylinder(h=5*d_hole, d=d_hole);
    translate([-d_hole*2, timber_construct_w*3/4, d_hole*1.5]) rotate([0,90,0]) cylinder(h=5*d_hole, d=d_hole);

  translate([-2.5, 0, -d_hole*1.5]) rotate([30,0,0]) cube([timber_construct_w+2.5+2.5,d_hole,d_hole*3]);
  translate([0, -2.5, -d_hole*1.5]) rotate([0,-30,0]) cube([d_hole,timber_construct_w+2.5+2.5,d_hole*3]);

  translate([-2.5, d_hole, d_hole*4.25]) rotate([-30,180,180]) cube([timber_construct_w+2.5+2.5,d_hole,d_hole*3]);
  translate([d_hole, -2.5, d_hole*4.25]) rotate([180,-30,180]) cube([d_hole,timber_construct_w+2.5+2.5,d_hole*3]);

}

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


adjust buttons diameter again

adjust buttons diameter again

$fn = 50;
button_h = 13;
overlap = 5;
total_height = 23;
th = 2; // enclosure thickness
eps = 1e-1;

cap_r = 7 / 2;
cap_h = total_height - button_h + overlap;

border_offset = 5.5 + th;
border_h = 3;
border_r = cap_r + 3;

socket_r = 3.2 / 2;

difference() {
  union() {
    cylinder(r=cap_r, h=cap_h);
    translate([0, 0, cap_h - border_h - border_offset]) {
      cylinder(r=border_r, h=border_h);
    }
  }
  translate([0, 0, -eps]) {
    cylinder(r=socket_r, h=overlap+eps);
  }
}

$fn = 50;
button_h = 13;
overlap = 5;
total_height = 23;
th = 2; // enclosure thickness
eps = 1e-1;

cap_r = 6.5 / 2;
cap_h = total_height - button_h + overlap;

border_offset = 5.5 + th;
border_h = 3;
border_r = cap_r + 3;

socket_r = 3.2 / 2;

difference() {
  union() {
    cylinder(r=cap_r, h=cap_h);
    translate([0, 0, cap_h - border_h - border_offset]) {
      cylinder(r=border_r, h=border_h);
    }
  }
  translate([0, 0, -eps]) {
    cylinder(r=socket_r, h=overlap+eps);
  }
}


support element added

support element added


put some useful small modules in an easier file to include

// miscelaneous utilility modules

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

module drillHole(holeRad) translate([0,0,-.03]) cylinder(h=22,r=holeRad,$fn=80);

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

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

module sphereSection(r,h,ar=1.5,off=-.3,fn=64) translate([0,0,h/2]) intersection() {
  cube([2*r,2*r,h],center=true);
  translate([0,0,off*h]) scale([1,1,ar]) sphere(r,$fn=fn);
}

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


small holder added, that latches to just 1 corner ECD board

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


fix: take care of the h parameter in buildVolume

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

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

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

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

    plateHeight = TESTBED_THICKNESS;
    lineWidth = .5;

    testbedExtrude(.2) {
        translate(center ? -plateSize / 2 : [0, 0]) {
            square(plateSize);
        }
    }
    testbedExtrude(.2) {
        translate(center ? [cellOffset.x, -plateSize.y / 2, 0] : ORIGIN_3D) {
            repeat(count=cellCount.x, intervalX=cellSize.x) {
                square([lineWidth, plateSize.y]);
            }
        }
        translate(center ? [-plateSize.x / 2, cellOffset.y, 0] : ORIGIN_3D) {
            repeat(count=cellCount.y, intervalY=cellSize.y) {
                square([plateSize.x, lineWidth]);
            }
        }
    }
}

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

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

    children();
}

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

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

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

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

    plateHeight = TESTBED_THICKNESS;
    lineWidth = .5;

    testbedExtrude(.2) {
        translate(center ? -plateSize / 2 : [0, 0]) {
            square(plateSize);
        }
    }
    testbedExtrude(.2) {
        translate(center ? [cellOffset.x, -plateSize.y / 2, 0] : ORIGIN_3D) {
            repeat(count=cellCount.x, intervalX=cellSize.x) {
                square([lineWidth, plateSize.y]);
            }
        }
        translate(center ? [-plateSize.x / 2, cellOffset.y, 0] : ORIGIN_3D) {
            repeat(count=cellCount.y, intervalY=cellSize.y) {
                square([plateSize.x, lineWidth]);
            }
        }
    }
}

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

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

    children();
}