x/extruder: more tweaks

x/extruder: more tweaks

use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/transforms.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;
use <thing_libutils/bearing.scad>
use <thing_libutils/metric-screw.scad>
use <thing_libutils/gears.scad>
include <thing_libutils/gears-data.scad>

include <config.scad>

xaxis_carriage_bearing_distance = 8*mm;
xaxis_carriage_padding = 4*mm;
xaxis_carriage_mount_distance = 23*mm;
xaxis_carriage_mount_offset_z = 0*mm;
xaxis_carriage_teeth_height=xaxis_belt_width*1.5;
xaxis_carriage_mount_screws = ThreadM4;

xaxis_carriage_conn = [[0, -xaxis_bearing[1]/2 - xaxis_carriage_bearing_offset_y,0], [0,0,0]];

xaxis_carriage_beltfasten_w = 20*mm;

hobbed_gear_d_outer = 12.65*mm;
hobbed_gear_d_inner = 11.5*mm;
hobbed_gear_h = 11*mm;

gear_60t_mod05 =[
[GearMod, 0.5],
[GearTeeth, 60]
];

gear_13t_mod05 =[
[GearMod, 0.5],
[GearTeeth, 13]
];

// 13t metal gear and 60t metal gear
extruder_gear_small = gear_13t_mod05;
extruder_gear_big = gear_60t_mod05;

extruder_gears_distance=calc_gears_center_distance(gear_60t_mod05,gear_13t_mod05);
extruder_gear_small_PD = calc_gear_PD(extruder_gear_small);
extruder_gear_big_PD = calc_gear_PD(extruder_gear_big);
extruder_gear_big_OD = calc_gear_OD(extruder_gear_big);

extruder_gear_big_h = [3.85*mm, 5*mm];
extruder_motor = dict_replace_multiple(Nema17,
        [
        [NemaLengthMedium, 11.75*mm],
        [NemaFrontAxleLength, 5*mm],
        ]);

// shaft from big gear to hobbed gear
extruder_shaft_d = 5*mm;

// dist between gear and motor
extruder_gear_motor_dist = .5*mm;
extruder_motor_angle = -80;
extruder_motor_offset_x = cos(extruder_motor_angle) * extruder_gears_distance;
extruder_motor_offset_z = sin(extruder_motor_angle) * extruder_gears_distance;
extruder_motor_holedist = lookup(NemaDistanceBetweenMountingHoles, extruder_motor);

extruder_gear_big_offset=[-extruder_motor_offset_x,0,extruder_motor_offset_z];

extruder_offset = [-2,0,10*mm];
extruder_offset_a = -extruder_gear_big_offset+[
    0,
    xaxis_bearing[1] + xaxis_carriage_bearing_offset_y + .2*mm,
    0];
extruder_filapath_offset = [hobbed_gear_d_inner/2, -12*mm, 0];

extruder_hotmount_clamp_nut = MHexNutM3;
extruder_hotmount_clamp_thread = ThreadM3;

MKnurlInsertNutM3_5_42 = [
    [MHexNutHoleDia, 3*mm],
    [MHexNutWidthMin, 4.2*mm-.4*mm],
    [MHexNutThickness, 5*mm],
    [MHexNutWidthMax, 4.2*mm],
    [MHexNutThread, ThreadM3],
    [MHexNutFacets, 10],
];

MKnurlInsertNutM3_3_42 = [
    [MHexNutHoleDia, 3*mm],
    [MHexNutWidthMin, 4.2*mm-.4*mm],
    [MHexNutThickness, 3*mm],
    [MHexNutWidthMax, 4.2*mm],
    [MHexNutThread, ThreadM3],
    [MHexNutFacets, 10],
];

extruder_a_h = 15*mm;

module x_carriage(mode=undef)
{
    bottom_width = xaxis_bearing[2] + 2*xaxis_carriage_padding;
    top_width = xaxis_bearing[2]*2 + xaxis_carriage_bearing_distance + 2*xaxis_carriage_padding;
    thickness = xaxis_bearing[1]/2 + xaxis_carriage_bearing_offset_y;

    if(mode==undef)
    {
        difference()
        {
            x_carriage(mode="pos");
            x_carriage(mode="neg");
        }
    }
    else
    if(mode=="pos")
    {
        hull()
        {
            // top bearings
            translate([0,0,xaxis_rod_distance/2])
                rcubea([top_width, thickness, xaxis_bearing[1]+xaxis_carriage_padding+ziptie_bearing_distance*2], align=[0,1,0]);

            /*rcubea([top_width,thickness,xaxis_rod_distance/2], align=[0,1,0]);*/

            // bottom bearing
            translate([0,0,-xaxis_rod_distance/2])
                rcubea([bottom_width, thickness, xaxis_bearing[1]+xaxis_carriage_padding+ziptie_bearing_distance*2], align=[0,1,0]);

        }
        translate([0,xaxis_bearing[1]/2+xaxis_carriage_bearing_offset_y+xaxis_carriage_beltpath_offset+.1,0])
        {
            translate([0,-xaxis_beltpath_width/2,0])
                for(x=[-1,1])
                    translate([x*(xaxis_carriage_beltfasten_w/2+5),-xaxis_beltpath_width/2,xaxis_pulley_inner_d/2])
                        rcubea([xaxis_carriage_beltfasten_w,xaxis_beltpath_width,xaxis_beltpath_height/3], align=[0,0,-1]);
        }
    }
    else if(mode=="neg")
    {
        for(i=[-1,1])
        translate([
                i*(xaxis_bearing[2]/2+xaxis_carriage_bearing_distance/2),
                xaxis_bearing[1]/2+xaxis_carriage_bearing_offset_y,
                xaxis_rod_distance/2
        ])
        {
            bearing_mount_holes(xaxis_bearing, orient=[1,0,0]);
            cubea([xaxis_bearing[2]*2,xaxis_bearing[1]/2+10,xaxis_bearing[1]+1*mm], align=[0,1,0]);
        }

        translate([
                0,
                xaxis_bearing[1]/2+xaxis_carriage_bearing_offset_y,
                -xaxis_rod_distance/2])
        {
            bearing_mount_holes(xaxis_bearing, orient=[1,0,0]);
            cubea([xaxis_bearing[2]*2,xaxis_bearing[1]/2+10,xaxis_bearing[1]+1*mm], align=[0,1,0]);
        }

        // Extruder mounting holes
        /*translate([0,0,xaxis_carriage_mount_offset_z])*/
        /*for(j=[-1,1])*/
        /*for(i=[-1,1])*/
        /*{*/
            /*translate([i*xaxis_carriage_mount_distance/2,0,j*xaxis_carriage_mount_distance/2])*/
            /*{*/
                /*screw_dia = lookup(ThreadSize, xaxis_carriage_mount_screws);*/
                /*cylindera(d=screw_dia, h=100, orient=[0,1,0]);*/
            /*}*/
        /*}*/

        translate([0,xaxis_carriage_beltpath_offset+.1,0])
        {
            // Cut clearing space for the belt
            /*translate([0,-xaxis_beltpath_width/2,-xaxis_beltpath_height/2])*/
                /*#rcubea([500,xaxis_beltpath_width+1,5], align=[0,1,0], extrasize=[0,0,4], extrasize_align=[0,0,1]);*/

            translate([0,-xaxis_beltpath_width/2,0])
            {
                difference()
                {
                    rcubea([500,xaxis_beltpath_width*2,xaxis_beltpath_height], align=[0,1,0]);
                    for(x=[-1,1])
                    translate([x*(xaxis_carriage_beltfasten_w/2+5),-xaxis_beltpath_width/2,xaxis_pulley_inner_d/2])
                        rcubea([xaxis_carriage_beltfasten_w,xaxis_beltpath_width*2,xaxis_beltpath_height/3], align=[0,1,-1]);
                }
            }

            /*belt_thickness=1.5;*/
            /*for(i=[-1,1])*/
                /*translate([i*30,0,0])*/
                    /*rcubea([15,xaxis_beltpath_width,15-belt_thickness], align=[0,0,0]);*/

            // Cut in the middle for belt
            /*rcubea([7,xaxis_beltpath_width,xaxis_beltpath_height], align=[0,0,0]);*/

            /*translate([0,-xaxis_beltpath_width/2,xaxis_pulley_inner_d/2])*/
            /*{*/
                /*// Belt slit*/
                /*rcubea([500,xaxis_beltpath_width,belt_thickness], align=[0,1,0]);*/

                /*[>// Teeth cuts<]*/
                /*[>teeth = 50;<]*/
                /*[>teeth_height = 2;<]*/
                /*[>translate([-belt_tooth_distance/2*teeth-.5,0,0])<]*/
                /*[>for(i=[0:teeth])<]*/
                /*[>{<]*/
                    /*[>translate([i*belt_tooth_distance,0,0])<]*/
                        /*[>cubea([belt_tooth_distance*belt_tooth_ratio,xaxis_carriage_teeth_height,teeth_height], align=[0,0,-1]);<]*/
                /*[>}<]*/
            /*}*/
        }
    }
    else if(mode=="vit")
    {
        for(x=[-1,1])
        translate([
                x*(xaxis_carriage_bearing_distance+xaxis_bearing[2])/2,
                xaxis_bearing[1]/2 + xaxis_carriage_bearing_offset_y,
                xaxis_rod_distance/2
        ])
            bearing(xaxis_bearing, orient=[1,0,0]);

        translate([
                0,
                xaxis_bearing[1]/2 + xaxis_carriage_bearing_offset_y,
                -xaxis_rod_distance/2
        ])
            bearing(xaxis_bearing, orient=[1,0,0]);

        /*translate([0,xaxis_carriage_beltpath_offset,0])*/
        /*for(i=[-1,1])*/
        /*translate([i*100,0,0])*/
        /*pulley(xaxis_idler_pulley, orient=[0,1,0]);*/
    }
}

module extruder_gear_small()
{
    difference()
    {
        union()
        {
            hull()
            {
                cylindera(d=extruder_gear_small_PD, h=7*mm, orient=[0,1,0], align=[0,1,0]);
                cylindera(d=10*mm, h= 3*mm, orient=[0,1,0], align=[0,1,0]);
            }
            cylindera(d=extruder_gear_small_PD, h=13*mm, orient=[0,1,0], align=[0,1,0]);
        }
        cylindera(d=5*mm, h=13*mm+.1, orient=[0,1,0], align=[0,1,0]);
    }
}

module extruder_gear_big(align=[0,0,0], orient=[0,0,1])
{
    total_h = extruder_gear_big_h[0]+extruder_gear_big_h[1];
    size_align([extruder_gear_big_PD, extruder_gear_big_PD, total_h], align=align, orient=orient)
    translate([0,0,-extruder_gear_big_h[0] + total_h/2])
    difference()
    {
        union()
        {
            cylindera(d=extruder_gear_big_PD, h=extruder_gear_big_h[0], orient=[0,0,1], align=[0,0,1]);
            cylindera(d=12*mm, h=extruder_gear_big_h[1], orient=[0,0,1], align=[0,0,-1]);
        }
        translate([0,0,-.5])
        cylindera(d=5*mm, h=total_h+.2, orient=[0,0,1], align=[0,0,0]);
    }
}

module extruder_a_motor_mount_cut(motor=Nema17, h=10*mm)
{
    screw_dist = lookup(NemaDistanceBetweenMountingHoles, motor);

    // round dia
    translate([0, .1, 0])
    cylindera(d=1.1*lookup(NemaRoundExtrusionDiameter, motor), h=h, orient=[0,1,0], align=[0,1,0]);

    // motor axle
    translate([0, .1, 0])
    cylindera(d=1.2*lookup(NemaAxleDiameter, motor), h=lookup(NemaFrontAxleLength, motor)+2*mm, orient=[0,1,0], align=[0,1,0]);

    // bearing for offloading force on motor shaft
    /*translate([0, -1*mm-xaxis_pulley[1]-.1, 0])*/
    scale(1.03)
    bearing(extruder_a_bearing, override_h=h, orient=[0,1,0], align=[0,-1,0]);

    motor_thread=ThreadM3;
    motor_nut=MHexNutM3;
    for(x=[-1,1])
    for(z=[-1,1])
    translate([x*screw_dist/2, -h, z*screw_dist/2])
    {
        if(x!=-1 || z!=-1)
        {
            screw_cut(motor_nut, h=h, with_nut=false, orient=[0,1,0], align=[0,1,0]);
        }
        else
        {
            // use knurl nut for the one screw that is hidden by gear
            translate([0,h,0])
            screw_cut(nut=MKnurlInsertNutM3_5_42, h=5*mm, orient=[0,-1,0], align=[0,-1,0]);
        }
    }
}

module extruder_a(show_vitamins=false)
{
    /*if(false)*/
    difference()
    {
        hull()
        /*union()*/
        {
            side = 15*mm;
            /*rcubea([extruder_motor_holedist+side/2+5*mm,extruder_a_h,extruder_motor_holedist+side/2], align=[0,1,0]);*/
            hull()
            {
                for(x=[-1,1])
                for(z=[-1,1])
                translate([(extruder_motor_holedist/2)*x,0,(extruder_motor_holedist/2)*z])
                rotate([0,x*45,0])
                rcubea([side/2,extruder_a_h,side/2], align=[0,1,0]);
            }
            translate(extruder_gear_big_offset)
            cylindera(d=extruder_gear_big_OD+2*mm+5*mm, h=extruder_a_h, orient=[0,1,0], align=[0,-1,0], round_radius=2);
        }

        //cutout for access to small gear tightscrew
        translate([0,0,lookup(NemaSideSize, extruder_motor)/2])
        translate([0,extruder_a_h,0])
        cylindera(d=11*mm, h=lookup(NemaSideSize, extruder_motor)/2, orient=[0,0,1], align=[0,0,-1]);

        //cutout for access to big gear tightscrew
        /*translate([-lookup(NemaSideSize, extruder_motor)/2,0,0])*/
        translate(extruder_gear_big_offset)
        translate([0,extruder_gear_big_h[0],0])
        translate([0,extruder_gear_big_h[1]/2+1*mm,0])
        rotate([0,-25,0])
        cylindera(d=7*mm, h=lookup(NemaSideSize, extruder_motor)/2, orient=[1,0,0], align=[-1,0,0]);

        translate([0,extruder_a_h,0])
        {
            translate(extruder_gear_big_offset)
            {
                // big gear cutout
                translate([0,-between_bearing_and_gear,0])
                translate([0,-extruder_a_bearing[2],0])
                translate([0,-extruder_gear_big_h[1],0])
                {
                    translate([0,2*mm,0])
                    cylindera(d=extruder_gear_big_OD+2*mm, h=extruder_a_h+.2, orient=[0,1,0], align=[0,1,0]);

                    translate([0,-.1,0])
                        cylindera(d=12*mm+3*mm, h=extruder_gear_big_h[1]+.2*mm, orient=[0,1,0], align=[0,-1,0]);
                }

                translate([0,.1,0])
                cylindera(d=extruder_shaft_d+1*mm, h=extruder_a_h+.2, orient=[0,1,0], align=[0,1,0]);

                translate([0,.1,0])
                scale(1.02)
                bearing(extruder_a_bearing, extra_h=.3*mm, orient=[0,1,0], align=[0,-1,0]);
            }

            extruder_a_motor_mount_cut(extruder_motor, h=extruder_a_h+1);
        }

    }

    between_bearing_and_gear=0*mm;
    /*if(false)*/
    if(show_vitamins)
    translate([0,extruder_a_h,0])
    {
        translate([0,-extruder_gear_motor_dist,0])
        {
            extruder_gear_small();

            // big gear
            translate(extruder_gear_big_offset)
            {
                translate([0,-between_bearing_and_gear,0])
                translate([0,-extruder_a_bearing[2],0])
                extruder_gear_big(orient=[0,-1,0], align=[0,-1,0]);

                bearing(extruder_a_bearing, orient=[0,1,0], align=[0,-1,0]);

                /*translate([0,extruder_a_bearing[2],0])*/
                {
                    cylindera(h=60*mm, d=extruder_shaft_d, orient=[0,1,0], align=[0,1,0]);
                }
            }
        }
        translate([0,-1*mm,0])
        motor(extruder_motor, NemaMedium, dualAxis=false, orientation=[-90,0,0]);
    }
}

// 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_xy=max(vec_i(hotmount_d_h,0))+5*mm;
hotmount_outer_size_h=max(vec_i(hotmount_d_h,1))+5*mm;
hotmount_offset_h=-5*mm;

// which side does hotend slide in (x-axis, i.e. -1 is left, 1 is right)
hotmount_tolerance=1.05*mm;

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

hotmount_clamp_screw_dia = lookup(ThreadSize, hotmount_clamp_thread);
hotmount_clamp_screws_dist = hotmount_d_h[1][1] + 1.2*hotmount_clamp_screw_dia;
hotmount_clamp_pad = 0;
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];

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;
            cylindera(d=d,h=h,align=[0,0,-1]);
            if(extend_cut)
            {
                cubea([extruder_b_w/2+1,d,h],align=[1,0,-1]);
            }
        }
    }
}

module hotmount_clamp()
{
    difference()
    {
        union()
        {
            translate([extruder_b_w/2, 0, 0]);
            {
                rcubea([hotmount_clamp_thickness, hotmount_clamp_y, hotmount_clamp_height], align=[-1,0,0]);
            }

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

                translate([(-extruder_b_w/2 * 1) + (-0.5*1), 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([.1, i*hotmount_clamp_screws_dist, 0])
                rotate([0,90,0])
                cylindera(d=lookup(ThreadSize, extruder_hotmount_clamp_thread), h=hotmount_clamp_thickness+.2, align=[0,0,-1], extra_h=2, round_radius=2);
        }
    }
}

extruder_a_bearing = bearing_MR105;

extruder_b_bearing = bearing_MR105;
extruder_b_w = hobbed_gear_d_outer+15*mm;

extruder_b_mount_thick = 5*mm;
extruder_b_mount_offsets=[
    [-1*(extruder_b_w/2+4*mm),0,0],
    [+1*(extruder_b_w/2+4*mm),0,0],
    [-4*mm,0,44.5*mm]
];

module extruder_b(part=undef)
{
    if(part==undef)
    {
        difference()
        {
            extruder_b(part="pos");
            extruder_b(part="neg");
        }
    }
    else if(part=="pos")
    {
        // mount onto carriage
        translate([extruder_filapath_offset[0],0,-15*mm])
        {
            hull()
            {
                for(pos=extruder_b_mount_offsets)
                translate(pos)
                cylindera(d=10*mm, h=extruder_b_mount_thick, orient=[0,1,0], align=[0,1,0], round_radius=2);
            }
        }

        hull()
        /*union()*/
        {
            // main house
            extruder_b_size=[
                hobbed_gear_d_outer+5*mm,
                abs(extruder_filapath_offset[1])+hobbed_gear_h/2+extruder_b_bearing[2]+4*mm,
                hobbed_gear_d_outer+5*mm
            ];
            /*translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])*/
            /*translate([hobbed_gear_d_inner/2,0,0])*/
            /*rcubea(extruder_b_size, align=[0,sign(extruder_filapath_offset[1]),0]);*/

            // gear support
            translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
            translate([0,-hobbed_gear_h/2,0])
            {
                // hobbed gear support
                cylindera(d=hobbed_gear_d_outer+5*mm, h=abs(extruder_filapath_offset[1])+hobbed_gear_h/2, align=[0,-1,0], orient=[0,1,0], round_radius=2);

                // bearing support
                cylindera(d=extruder_b_bearing[1]+5*mm, h=extruder_b_bearing[2]+3*mm, align=[0,1,0], orient=[0,1,0], round_radius=2);
            }

            // guidler screw nuts support
            translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
            translate([extruder_b_guidler_screw_offset_x, 0, extruder_b_guidler_screw_offset_h])
            {
                for(i=[-1,1])
                translate([0,i*(guidler_screws_distance),  0])
                cylindera(h=house_guidler_screw_h, d=guidler_screws_mount_d, orient=[1,0,0], round_radius=2);
            }

            // guidler mount
            translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
            translate(extruder_guidler_mount_off)
            {
                cylindera(d=guidler_mount_d, h=guidler_mount_w, orient=[0,1,0]);
            }

            // hotmount support
            translate(extruder_filapath_offset)
            translate([0,0,-hobbed_gear_d_outer/2 + hotmount_offset_h])
            {
                rcubea([extruder_b_w, hotmount_outer_size_xy, hotmount_outer_size_h], align=[0,0,-1]);

                translate([0,-extruder_filapath_offset[1],0])
                    rcubea([extruder_b_w, abs(extruder_filapath_offset[1]), hotmount_outer_size_h], align=[0,-1,-1]);
            }

            /*// clamp mount screw holes*/
            /*translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])*/
            /*translate([hobbed_gear_d_inner/2,0,-hobbed_gear_d_outer/2 + hotmount_offset_h])*/
            /*for(i=[-1,1])*/
            /*{*/
            /*translate([0, i*hotmount_clamp_screws_dist, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])*/
            /*cylindera(d=lookup(ThreadSize, extruder_hotmount_clamp_thread)+6*mm, h=extruder_b_w, orient=[1,0,0]);*/
            /*}*/
        }
    }
    else if(part=="neg")
    {
        // mount onto carriage
        translate([extruder_filapath_offset[0],0,-15*mm])
        {
            for(pos=extruder_b_mount_offsets)
            translate(pos)
            translate([0, -extruder_b_mount_thick-1*mm, 0])
            screw_cut(nut=MKnurlInsertNutM3_3_42, h=extruder_b_mount_thick, head_embed=true, nut_offset=-10, orient=[0,1,0], align=[0,1,0]);
        }

        // guidler cutout
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        {
            guidler_w_cut = guidler_w+2*mm;
            guidler_w_cut_inner = guidler_bearing[2]+1*mm;
            guidler_w_cut_ext = 1000*mm;
            difference()
            {
                union()
                {
                    /*hull()*/
                    {
                        /*hull()*/
                        {
                            translate([hobbed_gear_d_inner/2+3,0,0])
                            {
                                cubea([guidler_bearing[1]+1*mm,guidler_w_cut,guidler_bearing[1]*2], align=[1,0,1]);
                            }

                            // cut for guidler bearing
                            translate(extruder_guidler_mount_off)
                            translate(-[-guidler_mount_off[1],0,guidler_mount_off[2]])
                            cylindera(d=guidler_bearing[1], h=guidler_w_cut_inner, orient=[0,1,0], align=[0,0,0]);

                            // cut for guidler
                            translate(extruder_guidler_mount_off)
                            translate(-[-guidler_mount_off[1],0,guidler_mount_off[2]])
                            cylindera(d=guidler_bearing[0]*1.5+1*mm, h=guidler_w_cut, orient=[0,1,0], align=[0,0,0]);

                            // cutout pivot to make sure guidler can rotate out
                            guidler_pivot_r=pythag_hyp(abs(guidler_mount_off[1]),abs(guidler_mount_off[2]))+(guidler_bearing[1])/2;
                            translate([0,-guidler_w_cut/2,0])
                            translate(extruder_guidler_mount_off)
                            rotate([0,90,90])
                            pie_slice(guidler_pivot_r, 130, 270, guidler_w_cut, $fn=50);

                            translate([0,-guidler_w_cut/2,0])
                            translate(extruder_guidler_mount_off)
                            rotate([0,90,90])
                            pie_slice(guidler_pivot_r+4*mm, 125, 270, guidler_w_cut, $fn=50);
                        }

                        translate(extruder_guidler_mount_off)
                        {
                            hull()
                            for(y=[-1,1])
                            translate([0,y*guidler_mount_w/2,0])
                            {
                                cylindera(d=guidler_mount_d, h=guidler_mount_w, orient=[0,1,0], align=[0,-y,0]);
                                translate([-guidler_mount_d,0,-guidler_mount_d/2])
                                    cubea([10,(guidler_w-guidler_mount_w)/2+1*mm,10], align=[1,y,1]);
                            }
                        }
                    }
                    translate(extruder_guidler_mount_off)
                    {
                        cylindera(d=guidler_mount_d+2*mm, h=guidler_w_cut, orient=[0,1,0], align=[0,0,0]);
                        hull()
                        {
                            cylindera(d=guidler_screws_thread_dia+2*mm, h=guidler_w_cut_ext, orient=[0,1,0], align=[0,0,0]);
                            translate([0,0,-(guidler_screws_thread_dia+0*mm)])
                            cubea([10,guidler_w_cut_ext,100], align=[1,0,1]);
                        }
                    }
                }
                // dont cut away the guilder mount
                translate(extruder_guidler_mount_off)
                {
                    cylindera(d=guidler_mount_d, h=guidler_mount_w, orient=[0,1,0]);
                    cubea([guidler_mount_d, guidler_mount_w, 10], align=[0,0,-1]);
                }
            }
        }

        // guidler screws cutouts
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        for(y=[-1,1])
        translate([extruder_b_guidler_screw_offset_x, y*(guidler_screws_distance), extruder_b_guidler_screw_offset_h])
        {
            r= guidler_screws_thread_dia/2 * 1.1;
            cubea([1000, r*2, r]);

            for(v=[-1,1])
                translate([0,0, v*r/2])
                    cylindera(r=r,h=1000, orient=[1,0,0]);

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

        // guidler mount screw
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        translate(extruder_guidler_mount_off)
        {
            cylindera(d=lookup(ThreadSize, guidler_screws_thread), h=guidler_mount_w+.1, orient=[0,1,0]);
        }

        // cutout for hobbed gear (inner)
        cylindera(
                h=abs(extruder_filapath_offset[1])+hobbed_gear_h/2+1.1*mm,
                d=hobbed_gear_d_outer+1.5*mm,
                orient=[0,1,0],
                align=[0,1,0]
                );

        // hotmount clamp screws
        translate([hobbed_gear_d_inner/2, 0,-hobbed_gear_d_outer/2 + hotmount_offset_h])
        for(i=[-1,1])
        {
            translate([i*hotmount_clamp_screws_dist, 0, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
                screw_cut(nut=MKnurlInsertNutM3_5_42, h=1000, nut_offset=5*mm, head_embed=false, orient=[0,1,0], align=[0,-1,0]);
        }

        // filament path
        translate(extruder_filapath_offset)
        {
            // above drive gear
            cylindera(h=1000, d=filament_d+.7*mm, orient=[0,0,1], align=[0,0,1]);

            // below drive gear (into hotend)
            cylindera(h=1000, d=4*mm, orient=[0,0,1], align=[0,0,-1]);
        }

        // gear cutout
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        translate([0,-hobbed_gear_h/2-.5*mm,0])
        cylindera(d=extruder_b_bearing[1]+.3*mm, h=extruder_b_bearing[2]+.5*mm, align=[0,1,0], orient=[0,1,0]);

        // gear cutout
        cylindera(h=abs(extruder_filapath_offset[1])+hobbed_gear_h/2+extruder_b_bearing[2]+1*mm, d=extruder_b_bearing[1]+.1*mm, orient=[0,1,0], align=[0,1,0]);

        // extruder shaft
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        translate([0,-extruder_filapath_offset[1]+.1,0])
        cylindera(h=1000, d=extruder_shaft_d, orient=[0,1,0], align=[0,1,0]);

        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        translate([hobbed_gear_d_inner/2,0,-hobbed_gear_d_outer/2 + hotmount_offset_h+.01])
        rotate([0,0,-90])
        {
            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])
                    cylindera(d=lookup(ThreadSize, extruder_hotmount_clamp_thread), h=extruder_b_w+1, orient=[1,0,0]);
            }

            // hotmount clamp cutout
            translate([extruder_b_w/2, 0, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
            {
                rcubea([hotmount_clamp_thickness+1.2, hotmount_clamp_y+0.2, hotmount_clamp_height+0.2], align=[-1,0,0], extrasize=[100,0,0], extrasize_align=[1,0,0]);
            }
        }
    }
    else if(part=="vit")
    {
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        {
            translate([hobbed_gear_d_inner/2,0,-hobbed_gear_d_outer/2 + hotmount_offset_h+.01])
            translate([0, -extruder_b_w/2 * (1), -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
            rotate([0,0,-90])
            hotmount_clamp();

            translate([0,-hobbed_gear_h/2-extruder_b_bearing[2]-.5*mm,0])
            {
                cylindera(h=extruder_a_h+extruder_offset_a[1]-extruder_filapath_offset[1], d=extruder_shaft_d, orient=[0,1,0], align=[0,-1,0]);

                bearing(extruder_b_bearing, orient=[0,1,0], align=[0,1,0]);
            }

            // hobbed gear
            cylindera(h=hobbed_gear_h, d=hobbed_gear_d_inner, orient=[0,1,0], align=[0,0,0]);
            for(y=[-1,1])
            translate([0,y*hobbed_gear_h/2,0])
            {
                cylindera(h=hobbed_gear_h/3, d=hobbed_gear_d_outer, orient=[0,1,0], align=[0,y,0]);
            }
        }
    }
}

// Final part
module x_carriage_withmounts(show_vitamins=false)
{
    difference()
    {
        /*hull()*/
        union()
        {
            x_carriage(mode="pos");

            // extruder A mount
            translate(extruder_offset)
            translate(extruder_offset_a)
            {
                for(x=[-1,1])
                for(z=[-1,1])
                {
                    if(x!=-1||z!=-1)
                    translate([x*extruder_motor_holedist/2,0,z*extruder_motor_holedist/2])
                        cylindera(d=10*mm, h=extruder_offset_a[1], orient=[0,1,0], align=[0,1,0], round_radius=2);
                }
            }
        }

        x_carriage(mode="neg");

        // rod between extruder part A and B
        translate(extruder_offset)
        {
            cylindera(h=100*mm, d=extruder_shaft_d+2*mm, orient=[0,1,0], align=[0,0,0]);
        }

        // extruder A mount cutout
        translate(extruder_offset)
        translate(extruder_offset_a)
        translate(-[0,extruder_offset_a[1],0])
        {
            for(x=[-1,1])
            for(z=[-1,1])
            translate([x*extruder_motor_holedist/2,0,z*extruder_motor_holedist/2])
            translate([0,.1,0])
            screw_cut(
                    nut=MHexNutM3,
                    h=extruder_offset_a[1]+.2,
                    head_embed=true,
                    with_nut=false,
                    orient=[0,1,0],
                    align=[0,1,0]
                    );
        }

        // extruder B mount cutout
        translate(extruder_offset)
        /*translate(extruder_offset_b)*/
        translate([extruder_filapath_offset[0],0,-15*mm])
        {
            for(pos=extruder_b_mount_offsets)
            translate(pos)
            screw_cut(nut=MKnurlInsertNutM3_3_42, h=5, head_embed=false, orient=[0,1,0], align=[0,1,0]);
        }
    }

    if(show_vitamins)
    {
        x_carriage(mode="vit");
    }
}

/*translate([0,-42,38])*/
/*rotate([0,0,90])*/
/*translate([0,-1,-42])*/
/*translate([-83,25,-42])*/
/*rotate([90,0,0])*/
/*import("stl/i3R_Compact_E3Dv6_Extruder_1.75_01.STL");*/

module x_extruder_hotend()
{
    hotend_conn =[[0,0,27.8-hotmount_offset_h],[0,0,1]];
    translate(extruder_filapath_offset)
    attach(extruder_conn_hotend, hotend_conn)
        rotate([90,0,90])
        %import("stl/E3D_V6_1.75mm_Universal_HotEnd_Mockup.stl");

}

guidler_bearing = bearing_MR125;

guidler_mount_off = [0,-guidler_bearing[1]/1.8, -guidler_bearing[1]/1.4];
extruder_guidler_mount_off = [-.3*mm -guidler_mount_off[1]+hobbed_gear_d_outer/2+guidler_bearing[1]/2,0,guidler_mount_off[2]];

// length of the guidler bearing bolt/screw
guidler_mount_w=guidler_bearing[2];
guidler_mount_d=8*mm;
guidler_bolt_h=guidler_bearing[2]+4*mm;

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

guidler_screws_thread = ThreadM3;
guidler_screws_thread_dia= lookup(ThreadSize, guidler_screws_thread);
guidler_screws_distance=4*mm;
guidler_screws_mount_d = guidler_screws_thread_dia*3;

guidler_srew_distance = 10;

house_guidler_screw_h = guidler_screws_thread_dia+10*mm;

extruder_b_guidler_screw_offset_h = 15*mm + guidler_screws_thread_dia -6*mm;
extruder_b_guidler_screw_offset_x = 2*mm;

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

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

                // guidler bearing bolt holder
                cylindera(d=guidler_bearing[0]*1.5,h=guidler_w, orient=[1,0,0]);
            }

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off[1]-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[1], guidler_mount_off[2]])
                cylindera(d=guidler_mount_d,h=guidler_w, orient=[1,0,0]);
            }

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off[1]-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[1]-guidler_mount_d/2, extruder_b_guidler_screw_offset_h])
                cylindera(r=guidler_screws_thread_dia/2*3,h=guidler_d, align=[0,-1,0], orient=[0,1,0]);

            }
        }

        // cutouts for clamping screws
        for(i=[-1,1])
        translate([i*(guidler_screws_distance),guidler_mount_off[1]-guidler_mount_d/2, extruder_b_guidler_screw_offset_h])
        {
            r= guidler_screws_thread_dia/2*1.1;
            translate([0, -0.1, 0])
            {
                cubea([r*2,guidler_d+.2,r], align=[0,1,0]);
                for(v=[-1,1])
                translate([0, 0, v*r/2])
                {
                    cylindera(r=r,h=guidler_d+.2, align=[0,-1,0], orient=[0,1,0]);
                }
            }

        }

        // 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[1], guidler_mount_off[2]])
        cylindera(d=guidler_mount_d*1.25,h=guidler_mount_w*1.1, orient=[1,0,0]);

        // mount bolt hole
        translate([0,guidler_mount_off[1], guidler_mount_off[2]])
        cylindera(d=lookup(ThreadSize, guidler_screws_thread),h=100, orient=[1,0,0]);

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

            cylindera(d=guidler_bearing[0]*1.05, h=guidler_bolt_h*1.05, orient=[1,0,0]);
        }

        // guidler bearing cutout
        cylindera(d=guidler_bearing[1]*1.1, h=guidler_bearing[2]*1.1, orient=[1,0,0]);

    }

    if(show_extras)
    {
        cylindera(d=guidler_bearing[1], h=guidler_bearing[2], orient=[1,0,0]);
        cylindera(d=guidler_bearing[0], h=guidler_bolt_h, orient=[1,0,0]);
    }
}

// extruder guidler mount point
extruder_conn_guidler = [ extruder_guidler_mount_off, [0,1,0]];

// guidler connection point
extruder_guidler_conn_mount = [ guidler_mount_off,  [1,0,0]];
extruder_guidler_roll = 45;

if(false)
attach(extruder_conn_guidler, extruder_guidler_conn_mount, extruder_guidler_roll)
{
    extruder_guidler(show_extras=true);
}

if(false)
extruder_a(show_vitamins=true);

if(false)
{
    /*x_carriage_withmounts(show_vitamins=true);*/

    translate(extruder_offset)
    {
        translate(extruder_offset_a)
        extruder_a(show_vitamins=true);

        /*difference()*/
        /*{*/
            /*extruder_b(part="pos");*/

            /*extruder_b(part="neg");*/
        /*}*/
        /*extruder_b(part="vit");*/

        /*translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])*/
        /*attach(extruder_conn_guidler, extruder_guidler_conn_mount, extruder_guidler_roll)*/
        /*{*/
            /*extruder_guidler(show_extras=true);*/
        /*}*/

        /*x_extruder_hotend();*/

        /*//filament path*/
        /*translate(extruder_filapath_offset)*/
        /*cylindera(h=1000, d=1.75*mm, orient=[0,0,1], align=[0,0,0]);*/
    }
}

if(false)
{
    /*rotate([90,0,0])*/
    /*x_carriage_withmounts(show_vitamins=false);*/

    rotate([-90,0,0])
    extruder_a();

    /*rotate([-90,0,0])*/
    /*extruder_b();*/

    /*guidler_conn_layflat = [ [0, guidler_mount_off[1]-guidler_mount_d/2, guidler_mount_off[2]],  [0,-1,0]]; */
    /*attach([[0*mm,0*mm,0],[0,0,-1]], guidler_conn_layflat)*/
    /*{*/
        /*extruder_guidler(show_extras=false);*/
    /*}*/

    /*hotmount_clamp();*/
}

use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/transforms.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;
use <thing_libutils/bearing.scad>
use <thing_libutils/metric-screw.scad>
use <thing_libutils/gears.scad>
include <thing_libutils/gears-data.scad>

include <config.scad>

xaxis_carriage_bearing_distance = 8*mm;
xaxis_carriage_padding = 4*mm;
xaxis_carriage_mount_distance = 23*mm;
xaxis_carriage_mount_offset_z = 0*mm;
xaxis_carriage_teeth_height=xaxis_belt_width*1.5;
xaxis_carriage_mount_screws = ThreadM4;

xaxis_carriage_conn = [[0, -xaxis_bearing[1]/2 - xaxis_carriage_bearing_offset_y,0], [0,0,0]];

xaxis_carriage_beltfasten_w = 20*mm;

hobbed_gear_d_outer = 12.65*mm;
hobbed_gear_d_inner = 11.5*mm;
hobbed_gear_h = 11*mm;

gear_60t_mod05 =[
[GearMod, 0.5],
[GearTeeth, 60]
];

gear_13t_mod05 =[
[GearMod, 0.5],
[GearTeeth, 13]
];

// 13t metal gear and 60t metal gear
extruder_gear_small = gear_13t_mod05;
extruder_gear_big = gear_60t_mod05;

extruder_gears_distance=calc_gears_center_distance(gear_60t_mod05,gear_13t_mod05);
extruder_gear_small_PD = calc_gear_PD(extruder_gear_small);
extruder_gear_big_PD = calc_gear_PD(extruder_gear_big);
extruder_gear_big_OD = calc_gear_OD(extruder_gear_big);

extruder_gear_big_h = [3.85*mm, 5*mm];
extruder_motor = dict_replace_multiple(Nema17,
        [
        [NemaLengthMedium, 11.75*mm],
        [NemaFrontAxleLength, 5*mm],
        ]);

// shaft from big gear to hobbed gear
extruder_shaft_d = 5*mm;

// dist between gear and motor
extruder_gear_motor_dist = .5*mm;
extruder_motor_angle = -80;
extruder_motor_offset_x = cos(extruder_motor_angle) * extruder_gears_distance;
extruder_motor_offset_z = sin(extruder_motor_angle) * extruder_gears_distance;
extruder_motor_holedist = lookup(NemaDistanceBetweenMountingHoles, extruder_motor);

extruder_gear_big_offset=[-extruder_motor_offset_x,0,extruder_motor_offset_z];

extruder_offset = [-2,0,10*mm];
extruder_offset_a = -extruder_gear_big_offset+[
    0,
    xaxis_bearing[1] + xaxis_carriage_bearing_offset_y + .2*mm,
    0];
extruder_filapath_offset = [hobbed_gear_d_inner/2, -12*mm, 0];

extruder_hotmount_clamp_nut = MHexNutM3;
extruder_hotmount_clamp_thread = ThreadM3;

MKnurlInsertNutM3_5_42 = [
    [MHexNutHoleDia, 3*mm],
    [MHexNutWidthMin, 4.2*mm-.4*mm],
    [MHexNutThickness, 5*mm],
    [MHexNutWidthMax, 4.2*mm],
    [MHexNutThread, ThreadM3],
    [MHexNutFacets, 10],
];

MKnurlInsertNutM3_3_42 = [
    [MHexNutHoleDia, 3*mm],
    [MHexNutWidthMin, 4.2*mm-.4*mm],
    [MHexNutThickness, 3*mm],
    [MHexNutWidthMax, 4.2*mm],
    [MHexNutThread, ThreadM3],
    [MHexNutFacets, 10],
];

extruder_a_h = 14*mm;

module x_carriage(mode=undef)
{
    bottom_width = xaxis_bearing[2] + 2*xaxis_carriage_padding;
    top_width = xaxis_bearing[2]*2 + xaxis_carriage_bearing_distance + 2*xaxis_carriage_padding;
    thickness = xaxis_bearing[1]/2 + xaxis_carriage_bearing_offset_y;

    if(mode==undef)
    {
        difference()
        {
            x_carriage(mode="pos");
            x_carriage(mode="neg");
        }
    }
    else
    if(mode=="pos")
    {
        hull()
        {
            // top bearings
            translate([0,0,xaxis_rod_distance/2])
                rcubea([top_width, thickness, xaxis_bearing[1]+xaxis_carriage_padding+ziptie_bearing_distance*2], align=[0,1,0]);

            /*rcubea([top_width,thickness,xaxis_rod_distance/2], align=[0,1,0]);*/

            // bottom bearing
            translate([0,0,-xaxis_rod_distance/2])
                rcubea([bottom_width, thickness, xaxis_bearing[1]+xaxis_carriage_padding+ziptie_bearing_distance*2], align=[0,1,0]);

        }
        translate([0,xaxis_bearing[1]/2+xaxis_carriage_bearing_offset_y+xaxis_carriage_beltpath_offset+.1,0])
        {
            translate([0,-xaxis_beltpath_width/2,0])
                for(x=[-1,1])
                    translate([x*(xaxis_carriage_beltfasten_w/2+5),-xaxis_beltpath_width/2,xaxis_pulley_inner_d/2])
                        rcubea([xaxis_carriage_beltfasten_w,xaxis_beltpath_width,xaxis_beltpath_height/3], align=[0,0,-1]);
        }
    }
    else if(mode=="neg")
    {
        for(i=[-1,1])
        translate([
                i*(xaxis_bearing[2]/2+xaxis_carriage_bearing_distance/2),
                xaxis_bearing[1]/2+xaxis_carriage_bearing_offset_y,
                xaxis_rod_distance/2
        ])
        {
            bearing_mount_holes(xaxis_bearing, orient=[1,0,0]);
            cubea([xaxis_bearing[2]*2,xaxis_bearing[1]/2+10,xaxis_bearing[1]+1*mm], align=[0,1,0]);
        }

        translate([
                0,
                xaxis_bearing[1]/2+xaxis_carriage_bearing_offset_y,
                -xaxis_rod_distance/2])
        {
            bearing_mount_holes(xaxis_bearing, orient=[1,0,0]);
            cubea([xaxis_bearing[2]*2,xaxis_bearing[1]/2+10,xaxis_bearing[1]+1*mm], align=[0,1,0]);
        }

        // Extruder mounting holes
        /*translate([0,0,xaxis_carriage_mount_offset_z])*/
        /*for(j=[-1,1])*/
        /*for(i=[-1,1])*/
        /*{*/
            /*translate([i*xaxis_carriage_mount_distance/2,0,j*xaxis_carriage_mount_distance/2])*/
            /*{*/
                /*screw_dia = lookup(ThreadSize, xaxis_carriage_mount_screws);*/
                /*cylindera(d=screw_dia, h=100, orient=[0,1,0]);*/
            /*}*/
        /*}*/

        translate([0,xaxis_carriage_beltpath_offset+.1,0])
        {
            // Cut clearing space for the belt
            /*translate([0,-xaxis_beltpath_width/2,-xaxis_beltpath_height/2])*/
                /*#rcubea([500,xaxis_beltpath_width+1,5], align=[0,1,0], extrasize=[0,0,4], extrasize_align=[0,0,1]);*/

            translate([0,-xaxis_beltpath_width/2,0])
            {
                difference()
                {
                    rcubea([500,xaxis_beltpath_width*2,xaxis_beltpath_height], align=[0,1,0]);
                    for(x=[-1,1])
                    translate([x*(xaxis_carriage_beltfasten_w/2+5),-xaxis_beltpath_width/2,xaxis_pulley_inner_d/2])
                        rcubea([xaxis_carriage_beltfasten_w,xaxis_beltpath_width*2,xaxis_beltpath_height/3], align=[0,1,-1]);
                }
            }

            /*belt_thickness=1.5;*/
            /*for(i=[-1,1])*/
                /*translate([i*30,0,0])*/
                    /*rcubea([15,xaxis_beltpath_width,15-belt_thickness], align=[0,0,0]);*/

            // Cut in the middle for belt
            /*rcubea([7,xaxis_beltpath_width,xaxis_beltpath_height], align=[0,0,0]);*/

            /*translate([0,-xaxis_beltpath_width/2,xaxis_pulley_inner_d/2])*/
            /*{*/
                /*// Belt slit*/
                /*rcubea([500,xaxis_beltpath_width,belt_thickness], align=[0,1,0]);*/

                /*[>// Teeth cuts<]*/
                /*[>teeth = 50;<]*/
                /*[>teeth_height = 2;<]*/
                /*[>translate([-belt_tooth_distance/2*teeth-.5,0,0])<]*/
                /*[>for(i=[0:teeth])<]*/
                /*[>{<]*/
                    /*[>translate([i*belt_tooth_distance,0,0])<]*/
                        /*[>cubea([belt_tooth_distance*belt_tooth_ratio,xaxis_carriage_teeth_height,teeth_height], align=[0,0,-1]);<]*/
                /*[>}<]*/
            /*}*/
        }
    }
    else if(mode=="vit")
    {
        for(x=[-1,1])
        translate([
                x*(xaxis_carriage_bearing_distance+xaxis_bearing[2])/2,
                xaxis_bearing[1]/2 + xaxis_carriage_bearing_offset_y,
                xaxis_rod_distance/2
        ])
            bearing(xaxis_bearing, orient=[1,0,0]);

        translate([
                0,
                xaxis_bearing[1]/2 + xaxis_carriage_bearing_offset_y,
                -xaxis_rod_distance/2
        ])
            bearing(xaxis_bearing, orient=[1,0,0]);

        /*translate([0,xaxis_carriage_beltpath_offset,0])*/
        /*for(i=[-1,1])*/
        /*translate([i*100,0,0])*/
        /*pulley(xaxis_idler_pulley, orient=[0,1,0]);*/
    }
}

module extruder_gear_small()
{
    difference()
    {
        union()
        {
            hull()
            {
                cylindera(d=extruder_gear_small_PD, h=7*mm, orient=[0,1,0], align=[0,1,0]);
                cylindera(d=10*mm, h= 3*mm, orient=[0,1,0], align=[0,1,0]);
            }
            cylindera(d=extruder_gear_small_PD, h=13*mm, orient=[0,1,0], align=[0,1,0]);
        }
        cylindera(d=5*mm, h=13*mm+.1, orient=[0,1,0], align=[0,1,0]);
    }
}

module extruder_gear_big(align=[0,0,0], orient=[0,0,1])
{
    total_h = extruder_gear_big_h[0]+extruder_gear_big_h[1];
    size_align([extruder_gear_big_PD, extruder_gear_big_PD, total_h], align=align, orient=orient)
    translate([0,0,-extruder_gear_big_h[0] + total_h/2])
    difference()
    {
        union()
        {
            cylindera(d=extruder_gear_big_PD, h=extruder_gear_big_h[0], orient=[0,0,1], align=[0,0,1]);
            cylindera(d=12*mm, h=extruder_gear_big_h[1], orient=[0,0,1], align=[0,0,-1]);
        }
        translate([0,0,-.5])
        cylindera(d=5*mm, h=total_h+.2, orient=[0,0,1], align=[0,0,0]);
    }
}

module extruder_a_motor_mount_cut(motor=Nema17, h=10*mm)
{
    screw_dist = lookup(NemaDistanceBetweenMountingHoles, motor);

    // round dia
    translate([0, .1, 0])
    cylindera(d=1.1*lookup(NemaRoundExtrusionDiameter, motor), h=h, orient=[0,1,0], align=[0,1,0]);

    // motor axle
    translate([0, .1, 0])
    cylindera(d=1.2*lookup(NemaAxleDiameter, motor), h=lookup(NemaFrontAxleLength, motor)+2*mm, orient=[0,1,0], align=[0,1,0]);

    // bearing for offloading force on motor shaft
    /*translate([0, -1*mm-xaxis_pulley[1]-.1, 0])*/
    scale(1.03)
    bearing(bearing_MR105, override_h=h, orient=[0,1,0], align=[0,-1,0]);

    motor_thread=ThreadM3;
    motor_nut=MHexNutM3;
    for(x=[-1,1])
    for(z=[-1,1])
    translate([x*screw_dist/2, -h, z*screw_dist/2])
    {
        if(x!=-1 || z!=-1)
        {
            screw_cut(motor_nut, h=h, with_nut=false, orient=[0,1,0], align=[0,1,0]);
        }
        else
        {
            // use knurl nut for the one screw that is hidden by gear
            translate([0,h,0])
            screw_cut(nut=MKnurlInsertNutM3_5_42, h=5*mm, orient=[0,-1,0], align=[0,-1,0]);
        }
    }
}

module extruder_a(show_vitamins=false)
{
    difference()
    {
        hull()
        /*union()*/
        {
            side = 15*mm;
            rcubea([extruder_motor_holedist+side/2+5*mm,extruder_a_h,extruder_motor_holedist+side/2], align=[0,1,0]);
            /*hull()*/
            /*{*/
                /*for(x=[-1,1])*/
                /*for(z=[-1,1])*/
                /*translate([(extruder_motor_holedist/2)*x,0,(extruder_motor_holedist/2)*z])*/
                /*rotate([0,x*45,0])*/
                /*rcubea([side/2,extruder_a_h,side/2], align=[0,1,0]);*/
            /*}*/
            translate(extruder_gear_big_offset)
            cylindera(d=extruder_gear_big_OD+7*mm, h=extruder_a_h, orient=[0,1,0], align=[0,-1,0], round_radius=2);
        }

        translate([0,extruder_a_h,0])
        {
            translate(extruder_gear_big_offset)
            {
                /*scale([1.3,2.0,1.3])*/
                /*#extruder_gear_big(orient=[0,-1,0], align=[0,-1,0]);*/

                // big gear cutout
                translate([0,-bearing_MR105[2]+.1-4*mm,0])
                cylindera(d=extruder_gear_big_OD+2*mm, h=extruder_a_h+.2, orient=[0,1,0], align=[0,1,0]);

                translate([0,.1,0])
                cylindera(d=extruder_shaft_d+1*mm, h=extruder_a_h+.2, orient=[0,1,0], align=[0,1,0]);

                translate([0,.1,0])
                scale(1.03)
                bearing(bearing_MR105, override_h=6*mm, orient=[0,1,0], align=[0,-1,0]);
            }

            extruder_a_motor_mount_cut(extruder_motor, h=extruder_a_h+1);
        }

    }

    /*if(false)*/
    %if(show_vitamins)
    translate([0,extruder_a_h,0])
    {
        translate([0,-extruder_gear_motor_dist,0])
        {
            extruder_gear_small();

            // big gear
            translate(extruder_gear_big_offset)
            {
                translate([0,1,0])
                translate([0,-bearing_MR105[2]+.1,0])
                extruder_gear_big(orient=[0,-1,0], align=[0,-1,0]);

                translate([0,1,0])
                bearing(bearing_MR105, orient=[0,1,0], align=[0,-1,0]);

                translate([0,bearing_MR105[2],0])
                {
                    cylindera(h=60*mm, d=extruder_shaft_d, orient=[0,1,0], align=[0,1,0]);
                }
            }
        }
        motor(extruder_motor, NemaMedium, dualAxis=false, orientation=[-90,0,0]);
    }
}

// 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_xy=max(vec_i(hotmount_d_h,0))+5*mm;
hotmount_outer_size_h=max(vec_i(hotmount_d_h,1))+5*mm;
hotmount_offset_h=-5*mm;

// which side does hotend slide in (x-axis, i.e. -1 is left, 1 is right)
hotmount_tolerance=1.05*mm;

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

hotmount_clamp_screw_dia = lookup(ThreadSize, hotmount_clamp_thread);
hotmount_clamp_screws_dist = hotmount_d_h[1][1] + 1.2*hotmount_clamp_screw_dia;
hotmount_clamp_pad = 0;
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];

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;
            cylindera(d=d,h=h,align=[0,0,-1]);
            if(extend_cut)
            {
                cubea([extruder_b_w/2+1,d,h],align=[1,0,-1]);
            }
        }
    }
}

module hotmount_clamp()
{
    difference()
    {
        union()
        {
            translate([extruder_b_w/2, 0, 0]);
            {
                rcubea([hotmount_clamp_thickness, hotmount_clamp_y, hotmount_clamp_height], align=[-1,0,0]);
            }

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

                translate([(-extruder_b_w/2 * 1) + (-0.5*1), 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([.1, i*hotmount_clamp_screws_dist, 0])
                rotate([0,90,0])
                cylindera(d=lookup(ThreadSize, extruder_hotmount_clamp_thread), h=hotmount_clamp_thickness+.2, align=[0,0,-1], extra_h=2, round_radius=2);
        }
    }
}

extruder_b_bearing = bearing_MR105;
extruder_b_w = hobbed_gear_d_outer+15*mm;

extruder_b_mount_thick = 5*mm;
extruder_b_mount_offsets=[
    [-1*(extruder_b_w/2+4*mm),0,0],
    [+1*(extruder_b_w/2+4*mm),0,0],
    [-4*mm,0,44.5*mm]
];

module extruder_b(part=undef)
{
    if(part==undef)
    {
        difference()
        {
            extruder_b(part="pos");
            extruder_b(part="neg");
        }
    }
    else if(part=="pos")
    {
        // mount onto carriage
        translate([extruder_filapath_offset[0],0,-15*mm])
        {
            hull()
            {
                for(pos=extruder_b_mount_offsets)
                translate(pos)
                cylindera(d=10*mm, h=extruder_b_mount_thick, orient=[0,1,0], align=[0,1,0], round_radius=2);
            }
        }

        hull()
        /*union()*/
        {
            // main house
            extruder_b_size=[
                hobbed_gear_d_outer+5*mm,
                abs(extruder_filapath_offset[1])+hobbed_gear_h/2+extruder_b_bearing[2]+4*mm,
                hobbed_gear_d_outer+5*mm
            ];
            /*translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])*/
            /*translate([hobbed_gear_d_inner/2,0,0])*/
            /*rcubea(extruder_b_size, align=[0,sign(extruder_filapath_offset[1]),0]);*/

            // gear support
            translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
            translate([0,-hobbed_gear_h/2,0])
            {
                // hobbed gear support
                cylindera(d=hobbed_gear_d_outer+5*mm, h=abs(extruder_filapath_offset[1])+hobbed_gear_h/2, align=[0,-1,0], orient=[0,1,0], round_radius=2);

                // bearing support
                cylindera(d=extruder_b_bearing[1]+5*mm, h=extruder_b_bearing[2]+3*mm, align=[0,1,0], orient=[0,1,0], round_radius=2);
            }

            // guidler screw nuts support
            translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
            translate([extruder_b_guidler_screw_offset_x, 0, extruder_b_guidler_screw_offset_h])
            {
                for(i=[-1,1])
                translate([0,i*(guidler_screws_distance),  0])
                cylindera(h=house_guidler_screw_h, d=guidler_screws_mount_d, orient=[1,0,0], round_radius=2);
            }

            // guidler mount
            translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
            translate(extruder_guidler_mount_off)
            {
                cylindera(d=guidler_mount_d, h=guidler_mount_w, orient=[0,1,0]);
            }

            // hotmount support
            translate(extruder_filapath_offset)
            translate([0,0,-hobbed_gear_d_outer/2 + hotmount_offset_h])
            {
                rcubea([extruder_b_w, hotmount_outer_size_xy, hotmount_outer_size_h], align=[0,0,-1]);

                translate([0,-extruder_filapath_offset[1],0])
                    rcubea([extruder_b_w, abs(extruder_filapath_offset[1]), hotmount_outer_size_h], align=[0,-1,-1]);
            }

            /*// clamp mount screw holes*/
            /*translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])*/
            /*translate([hobbed_gear_d_inner/2,0,-hobbed_gear_d_outer/2 + hotmount_offset_h])*/
            /*for(i=[-1,1])*/
            /*{*/
            /*translate([0, i*hotmount_clamp_screws_dist, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])*/
            /*cylindera(d=lookup(ThreadSize, extruder_hotmount_clamp_thread)+6*mm, h=extruder_b_w, orient=[1,0,0]);*/
            /*}*/
        }
    }
    else if(part=="neg")
    {
        // mount onto carriage
        translate([extruder_filapath_offset[0],0,-15*mm])
        {
            for(pos=extruder_b_mount_offsets)
            translate(pos)
            translate([0, -extruder_b_mount_thick-1*mm, 0])
            screw_cut(nut=MKnurlInsertNutM3_3_42, h=extruder_b_mount_thick, head_embed=true, nut_offset=-10, orient=[0,1,0], align=[0,1,0]);
        }

        // guidler cutout
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        {
            guidler_w_cut = guidler_w+2*mm;
            guidler_w_cut_inner = guidler_bearing[2]+1*mm;
            guidler_w_cut_ext = 1000*mm;
            difference()
            {
                union()
                {
                    /*hull()*/
                    {
                        /*hull()*/
                        {
                            translate([hobbed_gear_d_inner/2+3,0,0])
                            {
                                cubea([guidler_bearing[1]+1*mm,guidler_w_cut,guidler_bearing[1]*2], align=[1,0,1]);
                            }

                            // cut for guidler bearing
                            translate(extruder_guidler_mount_off)
                            translate(-[-guidler_mount_off[1],0,guidler_mount_off[2]])
                            cylindera(d=guidler_bearing[1], h=guidler_w_cut_inner, orient=[0,1,0], align=[0,0,0]);

                            // cut for guidler
                            translate(extruder_guidler_mount_off)
                            translate(-[-guidler_mount_off[1],0,guidler_mount_off[2]])
                            cylindera(d=guidler_bearing[0]*1.5+1*mm, h=guidler_w_cut, orient=[0,1,0], align=[0,0,0]);

                            // cutout pivot to make sure guidler can rotate out
                            guidler_pivot_r=pythag_hyp(abs(guidler_mount_off[1]),abs(guidler_mount_off[2]))+(guidler_bearing[1])/2;
                            translate([0,-guidler_w_cut/2,0])
                            translate(extruder_guidler_mount_off)
                            rotate([0,90,90])
                            pie_slice(guidler_pivot_r, 130, 270, guidler_w_cut, $fn=50);

                            translate([0,-guidler_w_cut/2,0])
                            translate(extruder_guidler_mount_off)
                            rotate([0,90,90])
                            pie_slice(guidler_pivot_r+4*mm, 125, 270, guidler_w_cut, $fn=50);
                        }

                        translate(extruder_guidler_mount_off)
                        {
                            hull()
                            for(y=[-1,1])
                            translate([0,y*guidler_mount_w/2,0])
                            {
                                cylindera(d=guidler_mount_d, h=guidler_mount_w, orient=[0,1,0], align=[0,-y,0]);
                                translate([-guidler_mount_d,0,-guidler_mount_d/2])
                                    cubea([10,(guidler_w-guidler_mount_w)/2+1*mm,10], align=[1,y,1]);
                            }
                        }
                    }
                    translate(extruder_guidler_mount_off)
                    {
                        cylindera(d=guidler_mount_d+2*mm, h=guidler_w_cut, orient=[0,1,0], align=[0,0,0]);
                        hull()
                        {
                            cylindera(d=guidler_screws_thread_dia+2*mm, h=guidler_w_cut_ext, orient=[0,1,0], align=[0,0,0]);
                            translate([0,0,-(guidler_screws_thread_dia+0*mm)])
                            cubea([10,guidler_w_cut_ext,100], align=[1,0,1]);
                        }
                    }
                }
                // dont cut away the guilder mount
                translate(extruder_guidler_mount_off)
                {
                    cylindera(d=guidler_mount_d, h=guidler_mount_w, orient=[0,1,0]);
                    cubea([guidler_mount_d, guidler_mount_w, 10], align=[0,0,-1]);
                }
            }
        }

        // guidler screws cutouts
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        for(y=[-1,1])
        translate([extruder_b_guidler_screw_offset_x, y*(guidler_screws_distance), extruder_b_guidler_screw_offset_h])
        {
            r= guidler_screws_thread_dia/2 * 1.1;
            cubea([1000, r*2, r]);

            for(v=[-1,1])
                translate([0,0, v*r/2])
                    cylindera(r=r,h=1000, orient=[1,0,0]);

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

        // guidler mount screw
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        translate(extruder_guidler_mount_off)
        {
            cylindera(d=lookup(ThreadSize, guidler_screws_thread), h=guidler_mount_w+.1, orient=[0,1,0]);
        }

        // cutout for hobbed gear (inner)
        cylindera(
                h=abs(extruder_filapath_offset[1])+hobbed_gear_h/2+1.1*mm,
                d=hobbed_gear_d_outer+1.5*mm,
                orient=[0,1,0],
                align=[0,1,0]
                );

        // hotmount clamp screws
        translate([hobbed_gear_d_inner/2, 0,-hobbed_gear_d_outer/2 + hotmount_offset_h])
        for(i=[-1,1])
        {
            translate([i*hotmount_clamp_screws_dist, 0, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
                screw_cut(nut=MKnurlInsertNutM3_5_42, h=1000, nut_offset=5*mm, head_embed=false, orient=[0,1,0], align=[0,-1,0]);
        }

        // filament path
        translate(extruder_filapath_offset)
        {
            // above drive gear
            cylindera(h=1000, d=filament_d+.7*mm, orient=[0,0,1], align=[0,0,1]);

            // below drive gear (into hotend)
            cylindera(h=1000, d=4*mm, orient=[0,0,1], align=[0,0,-1]);
        }

        // gear cutout
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        translate([0,-hobbed_gear_h/2-.5*mm,0])
        cylindera(d=extruder_b_bearing[1]+.3*mm, h=extruder_b_bearing[2]+.5*mm, align=[0,1,0], orient=[0,1,0]);

        // gear cutout
        cylindera(h=abs(extruder_filapath_offset[1])+hobbed_gear_h/2+extruder_b_bearing[2]+1*mm, d=extruder_b_bearing[1]+.1*mm, orient=[0,1,0], align=[0,1,0]);

        // extruder shaft
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        translate([0,-extruder_filapath_offset[1]+.1,0])
        cylindera(h=1000, d=extruder_shaft_d, orient=[0,1,0], align=[0,1,0]);

        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        translate([hobbed_gear_d_inner/2,0,-hobbed_gear_d_outer/2 + hotmount_offset_h+.01])
        rotate([0,0,-90])
        {
            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])
                    cylindera(d=lookup(ThreadSize, extruder_hotmount_clamp_thread), h=extruder_b_w+1, orient=[1,0,0]);
            }

            // hotmount clamp cutout
            translate([extruder_b_w/2, 0, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
            {
                rcubea([hotmount_clamp_thickness+1.2, hotmount_clamp_y+0.2, hotmount_clamp_height+0.2], align=[-1,0,0], extrasize=[100,0,0], extrasize_align=[1,0,0]);
            }
        }
    }
    else if(part=="vit")
    {
        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        {
            translate([hobbed_gear_d_inner/2,0,-hobbed_gear_d_outer/2 + hotmount_offset_h+.01])
            translate([0, -extruder_b_w/2 * (1), -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
            rotate([0,0,-90])
            hotmount_clamp();

            translate([0,-hobbed_gear_h/2-extruder_b_bearing[2]-.5*mm,0])
            {
                cylindera(h=extruder_a_h+extruder_offset_a[1]-extruder_filapath_offset[1], d=extruder_shaft_d, orient=[0,1,0], align=[0,-1,0]);

                bearing(extruder_b_bearing, orient=[0,1,0], align=[0,1,0]);
            }

            // hobbed gear
            cylindera(h=hobbed_gear_h, d=hobbed_gear_d_inner, orient=[0,1,0], align=[0,0,0]);
            for(y=[-1,1])
            translate([0,y*hobbed_gear_h/2,0])
            {
                cylindera(h=hobbed_gear_h/3, d=hobbed_gear_d_outer, orient=[0,1,0], align=[0,y,0]);
            }
        }
    }
}

// Final part
module x_carriage_withmounts(show_vitamins=false)
{
    difference()
    {
        /*hull()*/
        union()
        {
            x_carriage(mode="pos");

            // extruder A mount
            translate(extruder_offset)
            translate(extruder_offset_a)
            {
                for(x=[-1,1])
                for(z=[-1,1])
                {
                    if(x!=-1||z!=-1)
                    translate([x*extruder_motor_holedist/2,0,z*extruder_motor_holedist/2])
                        cylindera(d=10*mm, h=extruder_offset_a[1], orient=[0,1,0], align=[0,1,0], round_radius=2);
                }
            }
        }

        x_carriage(mode="neg");

        // rod between extruder part A and B
        translate(extruder_offset)
        {
            cylindera(h=100*mm, d=extruder_shaft_d+2*mm, orient=[0,1,0], align=[0,0,0]);
        }

        // extruder A mount cutout
        translate(extruder_offset)
        translate(extruder_offset_a)
        translate(-[0,extruder_offset_a[1],0])
        {
            for(x=[-1,1])
            for(z=[-1,1])
            translate([x*extruder_motor_holedist/2,0,z*extruder_motor_holedist/2])
            translate([0,.1,0])
            screw_cut(
                    nut=MHexNutM3,
                    h=extruder_offset_a[1]+.2,
                    head_embed=true,
                    with_nut=false,
                    orient=[0,1,0],
                    align=[0,1,0]
                    );
        }

        // extruder B mount cutout
        translate(extruder_offset)
        /*translate(extruder_offset_b)*/
        translate([extruder_filapath_offset[0],0,-15*mm])
        {
            for(pos=extruder_b_mount_offsets)
            translate(pos)
            screw_cut(nut=MKnurlInsertNutM3_3_42, h=5, head_embed=false, orient=[0,1,0], align=[0,1,0]);
        }
    }

    if(show_vitamins)
    {
        x_carriage(mode="vit");
    }
}

/*translate([0,-42,38])*/
/*rotate([0,0,90])*/
/*translate([0,-1,-42])*/
/*translate([-83,25,-42])*/
/*rotate([90,0,0])*/
/*import("stl/i3R_Compact_E3Dv6_Extruder_1.75_01.STL");*/

module x_extruder_hotend()
{
    hotend_conn =[[0,0,27.8-hotmount_offset_h],[0,0,1]];
    translate(extruder_filapath_offset)
    attach(extruder_conn_hotend, hotend_conn)
        rotate([90,0,90])
        %import("stl/E3D_V6_1.75mm_Universal_HotEnd_Mockup.stl");

}

guidler_bearing = bearing_MR105;

guidler_mount_off = [0,-guidler_bearing[1]/1.8, -guidler_bearing[1]/1.6];
extruder_guidler_mount_off = [-.3*mm -guidler_mount_off[1]+hobbed_gear_d_outer/2+guidler_bearing[1]/2,0,guidler_mount_off[2]];

// length of the guidler bearing bolt/screw
guidler_mount_w=guidler_bearing[2];
guidler_mount_d=8*mm;
guidler_bolt_h=guidler_bearing[2]+4*mm;

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

guidler_screws_thread = ThreadM3;
guidler_screws_thread_dia= lookup(ThreadSize, guidler_screws_thread);
guidler_screws_distance=4*mm;
guidler_screws_mount_d = guidler_screws_thread_dia*3;

guidler_srew_distance = 10;

house_guidler_screw_h = guidler_screws_thread_dia+10*mm;

extruder_b_guidler_screw_offset_h = 15*mm + guidler_screws_thread_dia -6*mm;
extruder_b_guidler_screw_offset_x = 2*mm;

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

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

                // guidler bearing bolt holder
                cylindera(d=guidler_bearing[0]*1.5,h=guidler_w, orient=[1,0,0]);
            }

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off[1]-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[1], guidler_mount_off[2]])
                cylindera(d=guidler_mount_d,h=guidler_w, orient=[1,0,0]);
            }

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off[1]-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[1]-guidler_mount_d/2, extruder_b_guidler_screw_offset_h])
                cylindera(r=guidler_screws_thread_dia/2*3,h=guidler_d, align=[0,-1,0], orient=[0,1,0]);

            }
        }

        // cutouts for clamping screws
        for(i=[-1,1])
        translate([i*(guidler_screws_distance),guidler_mount_off[1]-guidler_mount_d/2, extruder_b_guidler_screw_offset_h])
        {
            r= guidler_screws_thread_dia/2*1.1;
            translate([0, -0.1, 0])
            {
                cubea([r*2,guidler_d+.2,r], align=[0,1,0]);
                for(v=[-1,1])
                translate([0, 0, v*r/2])
                {
                    cylindera(r=r,h=guidler_d+.2, align=[0,-1,0], orient=[0,1,0]);
                }
            }

        }

        // 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[1], guidler_mount_off[2]])
        cylindera(d=guidler_mount_d*1.25,h=guidler_mount_w*1.1, orient=[1,0,0]);

        // mount bolt hole
        translate([0,guidler_mount_off[1], guidler_mount_off[2]])
        cylindera(d=lookup(ThreadSize, guidler_screws_thread),h=100, orient=[1,0,0]);

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

            cylindera(d=guidler_bearing[0]*1.05, h=guidler_bolt_h*1.05, orient=[1,0,0]);
        }

        // guidler bearing cutout
        cylindera(d=guidler_bearing[1]*1.1, h=guidler_bearing[2]*1.1, orient=[1,0,0]);

    }

    if(show_extras)
    {
        cylindera(d=guidler_bearing[1], h=guidler_bearing[2], orient=[1,0,0]);
        cylindera(d=guidler_bearing[0], h=guidler_bolt_h, orient=[1,0,0]);
    }
}

// extruder guidler mount point
extruder_conn_guidler = [ extruder_guidler_mount_off, [0,1,0]];

// guidler connection point
extruder_guidler_conn_mount = [ guidler_mount_off,  [1,0,0]];
extruder_guidler_roll = 45;

if(false)
attach(extruder_conn_guidler, extruder_guidler_conn_mount, extruder_guidler_roll)
{
    extruder_guidler(show_extras=true);
}

if(false)
{
    x_carriage_withmounts(show_vitamins=true);

    translate(extruder_offset)
    {
        translate(extruder_offset_a)
        extruder_a(show_vitamins=true);

        difference()
        {
            extruder_b(part="pos");

            extruder_b(part="neg");
        }
        extruder_b(part="vit");

        translate(extruder_filapath_offset-[hobbed_gear_d_inner/2,0,0])
        attach(extruder_conn_guidler, extruder_guidler_conn_mount, extruder_guidler_roll)
        {
            extruder_guidler(show_extras=true);
        }

        x_extruder_hotend();

        //filament path
        translate(extruder_filapath_offset)
        cylindera(h=1000, d=1.75*mm, orient=[0,0,1], align=[0,0,0]);
    }
}

if(false)
{
    rotate([90,0,0])
    x_carriage_withmounts(show_vitamins=false);

    /*rotate([-90,0,0])*/
    /*extruder_a();*/

    /*rotate([-90,0,0])*/
    /*extruder_b();*/

    /*guidler_conn_layflat = [ [0, guidler_mount_off[1]-guidler_mount_d/2, guidler_mount_off[2]],  [0,-1,0]]; */
    /*attach([[0*mm,0*mm,0],[0,0,-1]], guidler_conn_layflat)*/
    /*{*/
        /*extruder_guidler(show_extras=false);*/
    /*}*/

    /*hotmount_clamp();*/
}


bearing: reduce rod cut dia to 1.3 instead of 1.5

use <shapes.scad>
include <bearing_data.scad>
include <units.scad>

module bearing(bearing_type, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    h = override_h==undef ? bearing_type[2] : override_h;
    size_align(size=[bearing_type[1],bearing_type[1],h], align=align ,orient=orient)
    difference()
    {
        // outer
        fncylindera(h=h, d=bearing_type[1], align=[0,0,0]);
        // inner
        fncylindera(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()
            {
                fncylindera(h=1*mm, d=bearing_type[2]+1, align=[0,0,-z]);
                fncylindera(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, show_zips=false)
{
    ziptie_thickness = ziptie_type[0];
    ziptie_width = ziptie_type[1]+0.6*mm;

    ziptie_dist_ = (ziptie_dist==undef?bearing_type[3]/2:ziptie_dist);

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

        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
        fncylindera(d=bearing_type[0]*1.3, 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,
                        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 <shapes.scad>
include <bearing_data.scad>
include <units.scad>

module bearing(bearing_type, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    h = override_h==undef ? bearing_type[2] : override_h;
    size_align(size=[bearing_type[1],bearing_type[1],h], align=align ,orient=orient)
    difference()
    {
        // outer
        fncylindera(h=h, d=bearing_type[1], align=[0,0,0]);
        // inner
        fncylindera(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()
            {
                fncylindera(h=1*mm, d=bearing_type[2]+1, align=[0,0,-z]);
                fncylindera(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, show_zips=false)
{
    ziptie_thickness = ziptie_type[0];
    ziptie_width = ziptie_type[1]+0.6*mm;

    ziptie_dist_ = (ziptie_dist==undef?bearing_type[3]/2:ziptie_dist);

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

        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
        fncylindera(d=bearing_type[0]*1.5, 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,
                        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]);
}


bladeValve draft

bladeValve draft

//Air Valve Prototype

//Variables
bladeH = 80;
bladeW = 20;
gearT = 5;
jointT = 5;
jointW = 5;

//Blade
module blade() {
    square([bladeW,bladeH],center=true);
    square([jointW,bladeH+2*(gearT+jointT)],center=true);
}

linear_extrude(height=5)blade();

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


Added bridge to hold a battery together with the computers

module holefixer() {
    //produces a holefixer (with space for a 3 mm screw)
    // it has 13 mm heigh
    // the center of the hole is at x=12,y=12
    difference() {
    union() {
        tickness = 3;
        cube([12, 10, tickness], center=true);
        translate([0,0,-15]) cylinder(h=16, r=3, center=false, $fn=100);
    }
            translate([0,0,-20]) cylinder(h=30, r=2, center=false, $fn=100);

        }

}

module bridge(covered = false) {
    color([1,1,1],1) {
        translate([0,44,0]) rotate([0,-90,0]) union() {
            cube([37, 24, 3]);
            translate([0,6,0]) cube([15, 12, 5]);
        }

        translate([76,44,0]) rotate([0,-90,0]) union() {
            cube([37, 24, 3]);
            translate([0,6,-2]) cube([15, 12, 5]);
        }
        if (covered == true) {
            translate([-3, 44, 37]) cube([79,24,3]);
        }
    }
}

$fn=100;
difference() {
    union() {
        tickness = 3;
        cube([74, 107, tickness]);
        translate([0,-33,0]) bridge(true);
        translate([0,28,0]) bridge(true);

        translate([-6,40,1.5]) holefixer();
        translate([-2,35,1.5]) cube([6, 10, 3], center=false);  //support to make outside wings stronger
        translate([79,40,1.5]) holefixer();
        translate([69,35,1.5]) cube([6, 10, 3], center=false); //support to make outside wings stronger

       translate([31.5, 44, 0]) cube([10, 4, 10], center=false);
       translate([26.5, 103, 0]) cube([20, 4, 10], center=false);
       translate([66, 74.5, 0]) cube([4, 10, 10], center=false);
    }

   translate([5.5, 7.5, 0])  cylinder(h=16, r=1.6, center=true);
   translate([14.1, -1, -1])  cube([18,16,7], center=false); // hole for ethernet card
   translate([64, 50, -1])  cube([6,18,7], center=false); //hole for firmware pins

   translate([66.3, 7.5, 0]) cylinder(h=16, r=1.6, center=true);

   translate([37, 75, 0]) cylinder(h=16, r=24, center=true);
//   translate([37, 20, 0]) cylinder(h=16, r=16, center=true);

}

module measureCheck() {
    color([1.0,0,0], 1) {
        rotate([0,90,0]) cylinder(h=85, r=1, center=false);
    }
}

//translate([-6,40,0]) measureCheck();

error: pathspec 'support-design/support-rocket-m5-rpi.scad' did not match any file(s) known to git


WIP on the model itself

WIP on the model itself

eps = 0.01;
spacing = 4;
size = [74.1+2*spacing, 32.2+2*spacing];
rounding = 5;

module holder_()
{
  z=2;
  x=74.1;
  y=32.2;
  w=3.08;
  for(dx=[0, x-w])
    translate([dx,0,0])
    {
      cube([w, y, z]);
      translate(6*[0, 1/2, 0])
        cube([w, y-6, z+20]);
    }
  translate([0, y/2-w/2, z])
    cube([x, w, z]);
}

module holder_space_()
{
  space=2;
  z=2-0.5;
  x=74.1;
  y=32.2+2*space;
  w=3.08+2*space;
  for(dx=[0, x-w+2*space])
    translate([dx, 0, 0])
      cube([w, y, z]);
}

module main_block_()
{
  // desk mount
//  difference()
//  {
//    cube([size[0], 19+2*2, 20+4]);
//    translate([-eps, 2, 4])
//      cube([size[0]+2*eps, 19, 20+1]);
//  }
  // main surface
  for(i=[0])//, size[0]-rounding])
    translate([i, 0, 0])
      hull()
      {
        cube([2*rounding+2, 1, 3]);
        for(j=[0, spacing])
          #translate(spacing*[1,0,0] + [j+1, size[1], 0])
            cylinder(r=rounding, h=3, $fn=120);
      }
}

module holder()
{
  difference()
  {
    main_block_();
    translate([2, spacing, 0])
      #holder_space_();
    translate(2*[1, 1, 0] + [size[0]-spacing-2, spacing, 1.5])
      rotate([0, 180, 0])
        %holder_();
  }
}

holder();

error: pathspec 'orp_orzeł_model_holder/holder.scad' did not match any file(s) known to git


animation

animation

// test parts for kinematic practicality

use <innerds.scad>;

springlen = 30;

for (i=[-1,0,1]){
    translate([0,i*(10+1),5/2])
        spring();
}

translate([0,0,17]){
    //%contact_ring(fat=1);
    nest_ring();
    translate([65,4,-2])
        contact_ring(fat=1);
}
//small_switch();

module spring(sl=springlen, sh=10, stp=2, tab=6){
    difference(){
        union(){
            // spring body
            cube([sl, sh, sh/2], center=true);
            // tabs for insertions
            for (i=[-sl/2-tab/2+1, sl/2+tab/2-1]){
                translate([i, 0, -sh/4+0.5])
                    minkowski(){
                        cube([tab-2, sh-2, 1-0.1], center=true);
                        cylinder(r=1, h=0.1, center=true, $fn=12);
                    }
            }
        }
        // diff out gaps
        for (i=[stp+1:stp*2:sl-stp/2], j=[-stp/2,stp/2]){
            translate([i-sl/2, stp/2, 0])
                cube([stp/2, sh+0.05,sh/2+0.1], center=true);
            translate([i-sl/2-stp, -stp/2, 0])
                cube([stp/2, sh+0.05,sh/2+0.1], center=true);
        }
        // holes in tabs
        for (i=[-sl/2-tab/2, sl/2+tab/2]){
            translate([i, 0, -sh/2+0.5])
                cylinder(r=1.7, h=sh, $fn=12, center=true);
        }
    }
}

module springcut(sl=springlen, sh=10, stp=2, tab=6){
    scale([1.0, 1.05, 1.05]){
        cube([sl, sh, sh/2], center=true);
        translate([0,0,-sh/4+0.5])
            cube([sl+tab*2, sh, 1], center=true);
        for (i=[-sl/2-tab/2, sl/2+tab/2]){
            translate([i, 0, -sh/4+0.5])
                cylinder(r=1.7, h=sh+1, $fn=12, center=true);
        }
    }
}

module alutube(OD=5.56, ID=4.7, ht=20){
    wedge=(OD-ID)/2;
    difference(){
        union(){
        translate([0,0,ht/2-wedge/2])
            cylinder(r1=OD/2, r2=ID/2, h=wedge+.05, center=true, $fn=round(OD*6));
        mirror([0,0,1]) translate([0,0,ht/2-wedge/2])
            cylinder(r1=OD/2, r2=OD/2, h=wedge, center=true, $fn=round(OD*6));
        cylinder(r=OD/2, h=(ht-wedge*2), center=true, $fn=round(OD*6));
        }
        cylinder(r=ID/2, h=ht+0.1, center=true, $fn=round(OD*6));
    }
}

module contact_ring(OD=58, wall=2, base=10, crown=5, ht=30, fat=1, sx=.3){
    springspot = 11;
    midwall=(OD*fat + (OD-wall*2*fat))/4 -.5;
    difference(){
        alutube(OD=OD*fat, ID=OD-wall*2*fat, ht=ht);
        for (i=[120,240,360]){
            translate([midwall*cos(i), midwall*sin(i), springspot]) rotate([i-180, -90,0])
                springcut();
        }
        for (i=[60,180,300]){
            translate([(midwall-sx)*cos(i), (midwall-sx)*sin(i), 14]) rotate([180, 0, i-90])
                small_switch();
        }
    }
    //redraw the spring-cuts as positives if needed for cut-out duty
    if (fat > 1){
        for (i=[120,240,360]){
            translate([midwall*cos(i), midwall*sin(i), springspot-4]) rotate([i-180, -90,0])
                scale([1, fat, fat])
                springcut();
        }
        for (i=[60,180,300]){
            translate([(midwall-sx)*cos(i), (midwall-sx)*sin(i), 14]) rotate([180, 0, i-90])
                small_switch();
        }
    }
}

module nest_ring(OD=64.6, wall=4.6, fat=1.00, ht=34){
    midwall=(OD*fat + (OD-wall*2*fat))/4;
    difference(){
        alutube(OD=OD, ID=OD-wall*2, ht=ht);
        translate([0,0,-13])
                contact_ring(fat=1.06);
    }
}

// test parts for kinematic practicality

use <innerds.scad>;

springlen = 29;

for (i=[-1,0,1]){
    translate([0,i*(10+1),5/2])
        spring();
}

translate([0,0,17]){
    //%contact_ring(fat=1);
    nest_ring();
    translate([65,4,-2])
        contact_ring(fat=1);
}
//small_switch();

module spring(sl=springlen, sh=10, stp=2, tab=6){
    difference(){
        union(){
            // spring body
            cube([sl, sh, sh/2], center=true);
            // tabs for insertions
            for (i=[-sl/2-tab/2+1, sl/2+tab/2-1]){
                translate([i, 0, -sh/4+0.5])
                    minkowski(){
                        cube([tab-2, sh-2, 1-0.1], center=true);
                        cylinder(r=1, h=0.1, center=true, $fn=12);
                    }
            }
        }
        // diff out gaps
        for (i=[stp+1:stp*2:sl-stp/2], j=[-stp/2,stp/2]){
            translate([i-sl/2, stp/2, 0])
                cube([stp/2, sh+0.05,sh/2+0.1], center=true);
            translate([i-sl/2-stp, -stp/2, 0])
                cube([stp/2, sh+0.05,sh/2+0.1], center=true);
        }
        // holes in tabs
        for (i=[-sl/2-tab/2, sl/2+tab/2]){
            translate([i, 0, -sh/2+0.5])
                cylinder(r=1.7, h=sh, $fn=12, center=true);
        }
    }
}

module springcut(sl=springlen, sh=10, stp=2, tab=6){
    scale([1.0, 1.05, 1.05]){
        cube([sl, sh, sh/2], center=true);
        translate([0,0,-sh/4+0.5])
            cube([sl+tab*2, sh, 1], center=true);
        for (i=[-sl/2-tab/2, sl/2+tab/2]){
            translate([i, 0, -sh/4+0.5])
                cylinder(r=1.7, h=sh+1, $fn=12, center=true);
        }
    }
}

module alutube(OD=5.56, ID=4.7, ht=20){
    wedge=(OD-ID)/2;
    difference(){
        union(){
        translate([0,0,ht/2-wedge/2])
            cylinder(r1=OD/2, r2=ID/2, h=wedge+.05, center=true, $fn=round(OD*6));
        mirror([0,0,1]) translate([0,0,ht/2-wedge/2])
            cylinder(r1=OD/2, r2=OD/2, h=wedge, center=true, $fn=round(OD*6));
        cylinder(r=OD/2, h=(ht-wedge*2), center=true, $fn=round(OD*6));
        }
        cylinder(r=ID/2, h=ht+0.1, center=true, $fn=round(OD*6));
    }
}

module contact_ring(OD=58, wall=2, base=10, crown=5, ht=30, fat=1, sx=.3){
    springspot = 11;
    midwall=(OD*fat + (OD-wall*2*fat))/4 -.5;
    difference(){
        alutube(OD=OD*fat, ID=OD-wall*2*fat, ht=ht);
        for (i=[120,240,360]){
            translate([midwall*cos(i), midwall*sin(i), springspot]) rotate([i-180, -90,0])
                springcut();
        }
        for (i=[60,180,300]){
            translate([(midwall-sx)*cos(i), (midwall-sx)*sin(i), 14]) rotate([180, 0, i-90])
                small_switch();
        }
    }
    //redraw the spring-cuts as positives if needed for cut-out duty
    if (fat > 1){
        for (i=[120,240,360]){
            translate([midwall*cos(i), midwall*sin(i), springspot-4]) rotate([i-180, -90,0])
                scale([1, fat, fat])
                springcut();
        }
        for (i=[60,180,300]){
            translate([(midwall-sx)*cos(i), (midwall-sx)*sin(i), 14]) rotate([180, 0, i-90])
                small_switch();
        }
    }
}

module nest_ring(OD=64.6, wall=4.6, fat=1.00, ht=34){
    midwall=(OD*fat + (OD-wall*2*fat))/4;
    difference(){
        alutube(OD=OD, ID=OD-wall*2, ht=ht);
        translate([0,0,-13])
                contact_ring(fat=1.06);
    }
}