main/yaxis: Add ycarriage print plate

main/yaxis: Add ycarriage print plate

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>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;
include <thing_libutils/timing-belts.scad>;

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>
include <extruder-direct.scad>
include <x-carriage.scad>
include <y-carriage.scad>
include <psu.scad>
include <rod-clamps.scad>

use <scad-utils/trajectory.scad>
use <scad-utils/trajectory_path.scad>
use <scad-utils/transformations.scad>
use <scad-utils/shapes.scad>
use <list-comprehension-demos/skin.scad>

axis_pos_x = 0*mm;
axis_range_z=[85,380];
axis_pos_z = axis_range_z[1]*mm/2;

module main()
{
    color(extrusion_color)
    gantry_lower();

    color(extrusion_color)
    translate([0,0,-main_lower_dist_z])
    gantry_lower();

    color(extrusion_color)
    for(i=[-1,1])
    translate([0,i*(main_upper_dist_y/2),0])
    gantry_upper();

    // x axis
    translate([0,0,axis_pos_z])
    {
        if(!preview_mode)
        {
            translate([0, xaxis_zaxis_distance_y, 0])
                belt_path(500, 6, xaxis_pulley_d);
        }

        translate([axis_pos_x,0,0])
        {
            // x carriage
            attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],[0,0,0]])
            {
                x_carriage(show_bearings=true);
            }

            if(!preview_mode)
            {
                attach([[12, -30, -30], [1,0,0]], extruder_conn_xcarriage)
                {
                    extruder();
                }
            }
        }

        // x smooth rods
        for(i=[-1,1])
            translate([0,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);

        translate([16,16,-8])
            translate([(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            /*translate([(xaxis_bearing_distance+xaxis_bearing[2])/2, xaxis_zaxis_distance_y, 0])*/
            idler_x_end();

        translate([-21,16,-8])
            translate([-(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            motor_x_end();
    }

    // y smooth rods
    translate([0,0,yaxis_bearing[0]/2])
    {
        for(i=[-1,1])
        for(j=[-1,1])
        {
            attach([[i*(yaxis_rod_distance/2),j*(main_depth/2+extrusion_size/2),0],[0,0,1]],mount_rod_clamp_conn_rod)
            {
                mount_rod_clamp_full(rod_d=zaxis_rod_d, thick=4, width=extrusion_size, thread=zmotor_mount_clamp_thread, orient=[0,1,0]);
            }
        }

        for(i=[-1,1])
        translate([i*(yaxis_rod_distance/2), 0, 0])
        {
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=[0,1,0]);

            for(j=[-1,1])
            {
                attach([[0,j*(yaxis_rod_distance/2),0],[0,0,-1]], ycarriage_bearing_mount_conn_bearing)
                {
                    ycarriage_bearing_mount(show_bearing=true, show_zips=true);
                }
            }
        }

        attach([[0,0,0],[0,0,-1]], ycarriage_bearing_mount_conn_bearing)
        {
            // y axis plate
            cubea(ycarriage_size, align=[0,0,-1]);

            translate([0,0,-10*mm])
                cubea(ycarriage_size, align=[0,0,-1]);
        }
    }

    // z axis
    for(i=[-1,1])
    {
        translate([i*(main_width/2),0,main_height])
        {
            mirror([i==-1?1:0,0,0])
            {
                upper_gantry_zrod_connector();

                translate([zmotor_mount_rod_offset_x, 0, extrusion_size/2])
                    mount_rod_clamp_half(
                            rod_d=zaxis_rod_d,
                            screw_dist=zmotor_mount_clamp_dist,
                            thick=5,
                            base_thick=5,
                            width=zmotor_mount_thickness_h,
                            thread=zmotor_mount_clamp_thread);
            }
        }

        translate([i*(main_width/2), 0, 0])
        {
            translate([0,0,zaxis_motor_offset_z])
                mirror([i==-1?1:0,0,0])
                {
                    zmotor_mount();
                    translate([zmotor_mount_rod_offset_x, 0, zmotor_mount_thickness_h/2])
                    {
                        mount_rod_clamp_half(
                                rod_d=zaxis_rod_d,
                                screw_dist=zmotor_mount_clamp_dist,
                                thick=5,
                                base_thick=5,
                                width=zmotor_mount_thickness_h,
                                thread=zmotor_mount_clamp_thread);
                    }

                    translate([(lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
                    attach([[0,0,0],[0,0,0]],zmotor_mount_conn_motor)
                    {
                        // z motor/leadscrews
                        motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
                    }
                }

            // z smooth rods
            translate([i*(lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            translate([i*(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
            {
                // z rods
                translate([0,0,zaxis_motor_offset_z-50])
                    fncylindera(h=zaxis_rod_l,d=zaxis_rod_d, align=[0,0,1]);

                for(j=[-1,1])
                    translate([0,0,axis_pos_z-j*xaxis_rod_distance/2])
                        bearing(zaxis_bearing);

            }

            translate([i*zmotor_mount_rod_offset_x, 0, axis_pos_z])
                #fncylindera(h=100, d=zaxis_nut[1], align=[0,0,0]);

            translate([i*zaxis_leadscrew_offset_x, 0, axis_pos_z-xaxis_rod_distance/2-10])
            {
                difference()
                {
                    #fncylindera(h=10, d=zaxis_nut[1], align=[0,0,0]);
                    union()
                    {
                        fncylindera(h=10+1, d=zaxis_nut[0], center= false);
                        translate([0, 13.5, -1]) fncylindera(h=5, r=1.6);
                        translate([0, -13.5, -1]) fncylindera(h=5, r=1.6);
                    }
                }
            }
        }
    }

    for(x=[-1,1])
    translate([x*(main_width/2-extrusion_size),main_depth/2,-main_lower_dist_z-extrusion_size])
    {
        translate([-x*psu_w/2, -psu_d/2, psu_h/2])
        {
            psu();

            mirror([x==-1?1:0,0,0])
            translate([0, -psu_screw_dist_y/2, 0])
                psu_extrusion_bracket_side();

            translate([0, psu_screw_dist_y/2, 0])
                psu_extrusion_bracket_back();
        }
    }
}

module upper_gantry_zrod_connector()
{
    upper_width_extra = main_upper_width-main_width;
    difference()
    {
        union()
        {
            hull()
            {
                // attach to z rod
                translate([lookup(NemaSideSize,zaxis_motor)/2, 0, 0])
                translate([(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
                {
                    cubea([gantry_connector_thickness, zmotor_mount_clamp_width, extrusion_size+gantry_connector_thickness], align=[-1,0,1]);
                }

                // connect upper gantry
                translate([upper_width_extra/2, 0, 0])
                    translate([0,0,extrusion_size/2])
                    cubea([gantry_connector_thickness,main_upper_dist_y+extrusion_size,extrusion_size], align=[1,0,0], extrasize=[0,0,gantry_connector_thickness], extrasize_align=[0,0,1]);
            }

            translate([upper_width_extra/2, 0, 0])
                translate([0,0,extrusion_size])
                cubea([extrusion_size*1.5,main_upper_dist_y+extrusion_size,gantry_connector_thickness], align=[-1,0,1]);

        }

        // cut out z rod mounting clamp nut traps and screw holes
        translate([0,0,extrusion_size/2])
        translate([upper_width_extra/2, 0, 0])
        for(i=[-1,1])
        {
            translate([-1, i*zmotor_mount_clamp_dist/2, 0])
            {
                fncylindera(fn=6, d=zmotor_mount_clamp_nut_dia, h=zmotor_mount_clamp_nut_thick, orient=[1,0,0], align=[1,0,0]);

                fncylindera(d=zmotor_mount_clamp_thread_dia, h=100, orient=[1,0,0], align=[1,0,0]);
            }
        }

        // cutout for z rod
        translate([lookup(NemaSideSize,zaxis_motor)/2, 0, 0])
        translate([(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,extrusion_size])
        fncylindera(d=zaxis_rod_d*1.01, h=extrusion_size*3, align=[0,0,0], orient=[0,0,1]);
    }
}

module zmotor_mount()
{

    difference()
    {
        // top plate
        union()
        {
            // top mount plate
            difference()
            {
                translate([0, 0,-extrusion_size-zaxis_motor_offset_z])
                    cubea([zmotor_mount_thickness, zmotor_mount_width, extrusion_size], align=[1,0,1]);

                for(i=[-1,1])
                    translate([0, i*(zmotor_w/2+zmotor_mount_thread_dia*3), -extrusion_size])
                        fncylindera(h=zmotor_mount_thickness*3,d=zmotor_mount_thread_dia, orient=[1,0,0]);
            }

            // bottom mount plate
            difference()
            {
                translate([0, 0, -main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
                    cubea([zmotor_mount_thickness, zmotor_mount_width, extrusion_size], align=[1,0,1]);

                for(i=[-1,1])
                    translate([0, i*(zmotor_w/2+zmotor_mount_thread_dia*3), -extrusion_size-main_lower_dist_z])
                        fncylindera(h=zmotor_mount_thickness*3,d=zmotor_mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
            }

            // side triangles
            for(i=[-1,1])
            {
                translate([zmotor_mount_thickness, i*((zmotor_w/2)+zmotor_mount_thickness/2), 0])
                    rotate([90,90,0])
                    Right_Angled_Triangle(a=zmotor_mount_rod_offset_x-zmotor_mount_thickness, b=main_lower_dist_z+extrusion_size+zaxis_motor_offset_z, height=zmotor_mount_thickness, centerXYZ=[0,0,1]);

                translate([0, i*((zmotor_w/2)+zmotor_mount_thickness/2), 0])
                    cubea([zmotor_mount_thickness, zmotor_mount_thickness, zmotor_mount_h], align=[1,0,-1]);
            }

            // top plate
            cubea([zmotor_mount_rod_offset_x-zmotor_mount_thickness, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[1,0,1]);
            translate([zmotor_mount_rod_offset_x, 0, 0])
            {
                cubea([gantry_connector_thickness, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[-1,0,1]);
            }
        }

        // cut out motor mount holes etc
        translate([zmotor_w/2+zmotor_mount_motor_offset,0,-1])
            linear_extrude(zmotor_mount_thickness_h+2)
            stepper_motor_mount(17, slide_distance=0, mochup=false);

        // cut out z rod
        translate([zmotor_mount_rod_offset_x, 0, 0])
            fncylindera(d=zaxis_rod_d*rod_fit_tolerance, h=100, orient=[0,0,1]);

        // cut out z rod mounting clamp nut traps
        for(i=[-1,1])
        {
            translate([zmotor_mount_rod_offset_x-7, i*zmotor_mount_clamp_dist/2, zmotor_mount_thickness_h/2])
            {
                cubea([zmotor_mount_clamp_nut_thick*1.1, zmotor_mount_clamp_nut_dia*1.01, zmotor_mount_clamp_nut_dia*1.01], extrasize=[0,0,zmotor_mount_thickness_h], extrasize_align=[0,0,1]);

                fncylindera(d=zmotor_mount_clamp_thread_dia, h=20, orient=[1,0,0], align=[1,0,0]);
            }
        }
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    {
        if(preview_mode)
        {
            cubea(size=[extrusion_size, extrusion_size, main_height], align=[-i,0,1]);
        }
        else
        {
            linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);
        }
    }

    translate([0, 0, main_height])
    {
        if(preview_mode)
        {
            cubea(size=[main_upper_width, extrusion_size, extrusion_size], align=[0,0,1]);
        }
        else
        {
            linear_extrusion(h=main_upper_width, align=[0,0,1], orient=[1,0,0]);
        }
    }
}

module gantry_lower()
{
    for(i=[-1,1])
    translate([0,  i*(main_depth/2), 0])
    {
        if(preview_mode)
        {
            cubea([main_width, extrusion_size, extrusion_size], align=[0,i,-1]);
        }
        else
        {
            linear_extrusion(h=main_width, align=[0,i,-1], orient=[1,0,0]);
        }
    }

    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    {
        if(preview_mode)
        {
            cubea([extrusion_size, main_depth, extrusion_size], align=[-i,0,-1]);
        }
        else
        {
            linear_extrusion(h=main_depth, align=[-i,0,-1], orient=[0,1,0]);
        }
    }
}

module belt_path(len=200, belt_width=6, pulley_d=10)
{
    belt=tGT2_2;
    rotate([90,0,0])
    translate([-len/2, -pulley_d/2, 0])
    {
        belt_len(belt, belt_width, len);
        translate([len,pulley_d,0]) rotate([0,0,180]) belt_len(belt, belt_width, len);
        translate([0,pulley_d,0]) rotate([0,0,180]) belt_angle(belt, pulley_d/2, belt_width, 180);
        translate([len,0,0]) rotate([0,0,0]) belt_angle(belt, pulley_d/2 ,belt_width,180);
    }
}

module enclosure()
{
    w=60*cm;
    h=60*cm;
    d=60*cm;
    wallthick=2*cm;
    backthick=0.5*cm;

    translate([0, 0, h/2])
    {
        // left/right walls
        for(i=[-1,1])
            translate([i*w/2,0,0])
                cubea([wallthick,d,h], align=[-i, 0, 0]);

        // back plate
        translate([0,d/2,0])
            cubea([w,backthick,h], align=[0,-1, 0]);

        // top/bottom plate
        for(i=[-1,1])
        translate([0,0,i*h/2])
            cubea([w-wallthick*2,d,wallthick], align=[0,0, -i]);
    }
}

translate([0, 0, main_lower_dist_z+extrusion_size*2])
main();

/*psu();*/

/*%enclosure();*/

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>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;
include <thing_libutils/timing-belts.scad>;

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>
include <extruder-direct.scad>
include <x-carriage.scad>
include <y-carriage.scad>
include <psu.scad>
include <rod-clamps.scad>

use <scad-utils/trajectory.scad>
use <scad-utils/trajectory_path.scad>
use <scad-utils/transformations.scad>
use <scad-utils/shapes.scad>
use <list-comprehension-demos/skin.scad>

axis_pos_x = 0*mm;
axis_range_z=[85,380];
axis_pos_z = axis_range_z[1]*mm/2;

module main()
{
    color(extrusion_color)
    gantry_lower();

    color(extrusion_color)
    translate([0,0,-main_lower_dist_z])
    gantry_lower();

    color(extrusion_color)
    for(i=[-1,1])
    translate([0,i*(main_upper_dist_y/2),0])
    gantry_upper();

    // x axis
    translate([0,0,axis_pos_z])
    {
        if(!preview_mode)
        {
            translate([0, xaxis_zaxis_distance_y, 0])
                belt_path(500, 6, xaxis_pulley_d);
        }

        translate([axis_pos_x,0,0])
        {
            // x carriage
            attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],[0,0,0]])
            {
                x_carriage(show_bearings=true);
            }

            if(!preview_mode)
            {
                attach([[12, -30, -30], [1,0,0]], extruder_conn_xcarriage)
                {
                    extruder();
                }
            }
        }

        // x smooth rods
        for(i=[-1,1])
            translate([0,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);

        translate([16,16,-8])
            translate([(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            /*translate([(xaxis_bearing_distance+xaxis_bearing[2])/2, xaxis_zaxis_distance_y, 0])*/
            idler_x_end();

        translate([-21,16,-8])
            translate([-(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            motor_x_end();
    }

    // y smooth rods
    translate([0,0,yaxis_bearing[0]/2])
    {
        for(i=[-1,1])
        for(j=[-1,1])
        {
            attach([[i*(yaxis_rod_distance/2),j*(main_depth/2+extrusion_size/2),0],[0,0,1]],mount_rod_clamp_conn_rod)
            {
                mount_rod_clamp_full(rod_d=zaxis_rod_d, thick=4, width=extrusion_size, thread=zmotor_mount_clamp_thread, orient=[0,1,0]);
            }
        }

        for(i=[-1,1])
        translate([i*(yaxis_rod_distance/2), 0, 0])
        {
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=[0,1,0]);

            for(j=[-1,1])
            {
                attach([[0,j*(yaxis_rod_distance/2),0],[0,0,-1]], ycarriage_bearing_mount_conn_bearing)
                {
                    ycarriage_bearing_mount(show_bearing=true, show_zips=true);
                }
            }
        }

        attach([[0,0,0],[0,0,-1]], ycarriage_bearing_mount_conn_bearing)
        {
            // y axis plate
            cubea(ycarriage_size, align=[0,0,-1]);
        }
    }

    // z axis
    for(i=[-1,1])
    {
        translate([i*(main_width/2),0,main_height])
        {
            mirror([i==-1?1:0,0,0])
            {
                upper_gantry_zrod_connector();

                translate([zmotor_mount_rod_offset_x, 0, extrusion_size/2])
                    mount_rod_clamp_half(
                            rod_d=zaxis_rod_d,
                            screw_dist=zmotor_mount_clamp_dist,
                            thick=5,
                            base_thick=5,
                            width=zmotor_mount_thickness_h,
                            thread=zmotor_mount_clamp_thread);
            }
        }

        translate([i*(main_width/2), 0, 0])
        {
            translate([0,0,zaxis_motor_offset_z])
                mirror([i==-1?1:0,0,0])
                {
                    zmotor_mount();
                    translate([zmotor_mount_rod_offset_x, 0, zmotor_mount_thickness_h/2])
                    {
                        mount_rod_clamp_half(
                                rod_d=zaxis_rod_d,
                                screw_dist=zmotor_mount_clamp_dist,
                                thick=5,
                                base_thick=5,
                                width=zmotor_mount_thickness_h,
                                thread=zmotor_mount_clamp_thread);
                    }

                    translate([(lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
                    attach([[0,0,0],[0,0,0]],zmotor_mount_conn_motor)
                    {
                        // z motor/leadscrews
                        motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
                    }
                }

            // z smooth rods
            translate([i*(lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            translate([i*(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
            {
                // z rods
                translate([0,0,zaxis_motor_offset_z-50])
                    fncylindera(h=zaxis_rod_l,d=zaxis_rod_d, align=[0,0,1]);

                for(j=[-1,1])
                    translate([0,0,axis_pos_z-j*xaxis_rod_distance/2])
                        bearing(zaxis_bearing);

            }

            translate([i*zmotor_mount_rod_offset_x, 0, axis_pos_z])
                #fncylindera(h=100, d=zaxis_nut[1], align=[0,0,0]);

            translate([i*zaxis_leadscrew_offset_x, 0, axis_pos_z-xaxis_rod_distance/2-10])
            {
                difference()
                {
                    #fncylindera(h=10, d=zaxis_nut[1], align=[0,0,0]);
                    union()
                    {
                        fncylindera(h=10+1, d=zaxis_nut[0], center= false);
                        translate([0, 13.5, -1]) fncylindera(h=5, r=1.6);
                        translate([0, -13.5, -1]) fncylindera(h=5, r=1.6);
                    }
                }
            }
        }
    }

    for(x=[-1,1])
    translate([x*(main_width/2-extrusion_size),main_depth/2,-main_lower_dist_z-extrusion_size])
    {
        translate([-x*psu_w/2, -psu_d/2, psu_h/2])
        {
            psu();

            mirror([x==-1?1:0,0,0])
            translate([0, -psu_screw_dist_y/2, 0])
                psu_extrusion_bracket_side();

            translate([0, psu_screw_dist_y/2, 0])
                psu_extrusion_bracket_back();
        }
    }
}

module upper_gantry_zrod_connector()
{
    upper_width_extra = main_upper_width-main_width;
    difference()
    {
        union()
        {
            hull()
            {
                // attach to z rod
                translate([lookup(NemaSideSize,zaxis_motor)/2, 0, 0])
                translate([(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
                {
                    cubea([gantry_connector_thickness, zmotor_mount_clamp_width, extrusion_size+gantry_connector_thickness], align=[-1,0,1]);
                }

                // connect upper gantry
                translate([upper_width_extra/2, 0, 0])
                    translate([0,0,extrusion_size/2])
                    cubea([gantry_connector_thickness,main_upper_dist_y+extrusion_size,extrusion_size], align=[1,0,0], extrasize=[0,0,gantry_connector_thickness], extrasize_align=[0,0,1]);
            }

            translate([upper_width_extra/2, 0, 0])
                translate([0,0,extrusion_size])
                cubea([extrusion_size*1.5,main_upper_dist_y+extrusion_size,gantry_connector_thickness], align=[-1,0,1]);

        }

        // cut out z rod mounting clamp nut traps and screw holes
        translate([0,0,extrusion_size/2])
        translate([upper_width_extra/2, 0, 0])
        for(i=[-1,1])
        {
            translate([-1, i*zmotor_mount_clamp_dist/2, 0])
            {
                fncylindera(fn=6, d=zmotor_mount_clamp_nut_dia, h=zmotor_mount_clamp_nut_thick, orient=[1,0,0], align=[1,0,0]);

                fncylindera(d=zmotor_mount_clamp_thread_dia, h=100, orient=[1,0,0], align=[1,0,0]);
            }
        }

        // cutout for z rod
        translate([lookup(NemaSideSize,zaxis_motor)/2, 0, 0])
        translate([(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,extrusion_size])
        fncylindera(d=zaxis_rod_d*1.01, h=extrusion_size*3, align=[0,0,0], orient=[0,0,1]);
    }
}

module zmotor_mount()
{

    difference()
    {
        // top plate
        union()
        {
            // top mount plate
            difference()
            {
                translate([0, 0,-extrusion_size-zaxis_motor_offset_z])
                    cubea([zmotor_mount_thickness, zmotor_mount_width, extrusion_size], align=[1,0,1]);

                for(i=[-1,1])
                    translate([0, i*(zmotor_w/2+zmotor_mount_thread_dia*3), -extrusion_size])
                        fncylindera(h=zmotor_mount_thickness*3,d=zmotor_mount_thread_dia, orient=[1,0,0]);
            }

            // bottom mount plate
            difference()
            {
                translate([0, 0, -main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
                    cubea([zmotor_mount_thickness, zmotor_mount_width, extrusion_size], align=[1,0,1]);

                for(i=[-1,1])
                    translate([0, i*(zmotor_w/2+zmotor_mount_thread_dia*3), -extrusion_size-main_lower_dist_z])
                        fncylindera(h=zmotor_mount_thickness*3,d=zmotor_mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
            }

            // side triangles
            for(i=[-1,1])
            {
                translate([zmotor_mount_thickness, i*((zmotor_w/2)+zmotor_mount_thickness/2), 0])
                    rotate([90,90,0])
                    Right_Angled_Triangle(a=zmotor_mount_rod_offset_x-zmotor_mount_thickness, b=main_lower_dist_z+extrusion_size+zaxis_motor_offset_z, height=zmotor_mount_thickness, centerXYZ=[0,0,1]);

                translate([0, i*((zmotor_w/2)+zmotor_mount_thickness/2), 0])
                    cubea([zmotor_mount_thickness, zmotor_mount_thickness, zmotor_mount_h], align=[1,0,-1]);
            }

            // top plate
            cubea([zmotor_mount_rod_offset_x-zmotor_mount_thickness, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[1,0,1]);
            translate([zmotor_mount_rod_offset_x, 0, 0])
            {
                cubea([gantry_connector_thickness, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[-1,0,1]);
            }
        }

        // cut out motor mount holes etc
        translate([zmotor_w/2+zmotor_mount_motor_offset,0,-1])
            linear_extrude(zmotor_mount_thickness_h+2)
            stepper_motor_mount(17, slide_distance=0, mochup=false);

        // cut out z rod
        translate([zmotor_mount_rod_offset_x, 0, 0])
            fncylindera(d=zaxis_rod_d*rod_fit_tolerance, h=100, orient=[0,0,1]);

        // cut out z rod mounting clamp nut traps
        for(i=[-1,1])
        {
            translate([zmotor_mount_rod_offset_x-7, i*zmotor_mount_clamp_dist/2, zmotor_mount_thickness_h/2])
            {
                cubea([zmotor_mount_clamp_nut_thick*1.1, zmotor_mount_clamp_nut_dia*1.01, zmotor_mount_clamp_nut_dia*1.01], extrasize=[0,0,zmotor_mount_thickness_h], extrasize_align=[0,0,1]);

                fncylindera(d=zmotor_mount_clamp_thread_dia, h=20, orient=[1,0,0], align=[1,0,0]);
            }
        }
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    {
        if(preview_mode)
        {
            cubea(size=[extrusion_size, extrusion_size, main_height], align=[-i,0,1]);
        }
        else
        {
            linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);
        }
    }

    translate([0, 0, main_height])
    {
        if(preview_mode)
        {
            cubea(size=[main_upper_width, extrusion_size, extrusion_size], align=[0,0,1]);
        }
        else
        {
            linear_extrusion(h=main_upper_width, align=[0,0,1], orient=[1,0,0]);
        }
    }
}

module gantry_lower()
{
    for(i=[-1,1])
    translate([0,  i*(main_depth/2), 0])
    {
        if(preview_mode)
        {
            cubea([main_width, extrusion_size, extrusion_size], align=[0,i,-1]);
        }
        else
        {
            linear_extrusion(h=main_width, align=[0,i,-1], orient=[1,0,0]);
        }
    }

    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    {
        if(preview_mode)
        {
            cubea([extrusion_size, main_depth, extrusion_size], align=[-i,0,-1]);
        }
        else
        {
            linear_extrusion(h=main_depth, align=[-i,0,-1], orient=[0,1,0]);
        }
    }
}

module belt_path(len=200, belt_width=6, pulley_d=10)
{
    belt=tGT2_2;
    rotate([90,0,0])
    translate([-len/2, -pulley_d/2, 0])
    {
        belt_len(belt, belt_width, len);
        translate([len,pulley_d,0]) rotate([0,0,180]) belt_len(belt, belt_width, len);
        translate([0,pulley_d,0]) rotate([0,0,180]) belt_angle(belt, pulley_d/2, belt_width, 180);
        translate([len,0,0]) rotate([0,0,0]) belt_angle(belt, pulley_d/2 ,belt_width,180);
    }
}

module enclosure()
{
    w=60*cm;
    h=60*cm;
    d=60*cm;
    wallthick=2*cm;
    backthick=0.5*cm;

    translate([0, 0, h/2])
    {
        // left/right walls
        for(i=[-1,1])
            translate([i*w/2,0,0])
                cubea([wallthick,d,h], align=[-i, 0, 0]);

        // back plate
        translate([0,d/2,0])
            cubea([w,backthick,h], align=[0,-1, 0]);

        // top/bottom plate
        for(i=[-1,1])
        translate([0,0,i*h/2])
            cubea([w-wallthick*2,d,wallthick], align=[0,0, -i]);
    }
}

translate([0, 0, main_lower_dist_z+extrusion_size*2])
main();

/*psu();*/

/*%enclosure();*/


fixup! main/y-axis: Add y-axis rod clamps

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>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;
include <thing_libutils/timing-belts.scad>;

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>
include <misc.scad>
include <extruder-direct.scad>
include <x-carriage.scad>
include <y-axis.scad>
include <z-axis.scad>
include <psu.scad>
include <rod-clamps.scad>

use <scad-utils/trajectory.scad>
use <scad-utils/trajectory_path.scad>
use <scad-utils/transformations.scad>
use <scad-utils/shapes.scad>
use <list-comprehension-demos/skin.scad>

axis_pos_x = 0*mm;
axis_range_z=[85,380];
axis_pos_z = axis_range_z[1]*mm/2;

module main()
{
    color(extrusion_color)
    gantry_lower();

    color(extrusion_color)
    translate([0,0,-main_lower_dist_z])
    gantry_lower();

    color(extrusion_color)
    for(i=[-1,1])
    translate([0,i*(main_upper_dist_y/2),0])
    gantry_upper();

    // x axis
    translate([0,0,axis_pos_z])
    {
        if(!preview_mode)
        {
            translate([0, xaxis_zaxis_distance_y, 0])
                belt_path(500, 6, xaxis_pulley_d, orient=[1,0,0]);
        }

        translate([axis_pos_x,0,0])
        {
            // x carriage
            attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],[0,0,0]])
            {
                x_carriage(show_bearings=true);
            }

            if(!preview_mode)
            {
                attach([[12, -30, -30], [1,0,0]], extruder_conn_xcarriage)
                {
                    extruder();
                }
            }
        }

        // x smooth rods
        for(i=[-1,1])
            translate([0,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);
    }

    // y axis
    attach([[0,main_depth/2,0], [0,-1,0]], yaxis_motor_mount_conn)
    {
        yaxis_motor_mount();

        attach([[0,0,0],[0,0,0]], yaxis_motor_mount_conn_motor)
        {
            motor(yaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);

            translate([0,0,5*mm])
            fncylindera(d=yaxis_pulley_d, h=10*mm, orient=[0,0,1]);
        }
    }

    translate([0,0,yaxis_bearing[0]/2])
    {
        if(!preview_mode)
        {
            belt_path(main_depth-yaxis_motor_offset*2, 6, yaxis_pulley_d, orient=[0,1,0]);
        }

        for(i=[-1,1])
        for(j=[-1,1])
        {
            attach([[i*(yaxis_rod_distance/2),j*(main_depth/2+extrusion_size/2),0],[0,0,1]],mount_rod_clamp_conn_rod)
            {
                mount_rod_clamp_full(rod_d=zaxis_rod_d, thick=4, width=extrusion_size, thread=zmotor_mount_clamp_thread, orient=[0,1,0]);
            }
        }

        for(i=[-1,1])
        translate([i*(yaxis_rod_distance/2), 0, 0])
        {
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=[0,1,0]);

            for(j=[-1,1])
            {
                attach([[0,j*(yaxis_rod_distance/2),0],[0,0,-1]], ycarriage_bearing_mount_conn_bearing)
                {
                    ycarriage_bearing_mount(show_bearing=true, show_zips=true);
                }
            }
        }

        attach([[0,0,0],[0,0,-1]], ycarriage_bearing_mount_conn_bearing)
        {
            // y axis plate
            cubea(ycarriage_size, align=[0,0,-1]);

            translate([0,0,-10*mm])
                cubea(ycarriage_size, align=[0,0,-1]);
        }
    }

    // z axis
    for(i=[-1,1])
    {
        translate([i*(main_width/2),0,main_height])
        {
            mirror([i==-1?1:0,0,0])
            {
                upper_gantry_zrod_connector();

                translate([zmotor_mount_rod_offset_x, 0, extrusion_size/2])
                    mount_rod_clamp_half(
                            rod_d=zaxis_rod_d,
                            screw_dist=zmotor_mount_clamp_dist,
                            thick=5,
                            base_thick=5,
                            width=zmotor_mount_thickness_h,
                            thread=zmotor_mount_clamp_thread);
            }
        }

        translate([i*(main_width/2), 0, 0])
        {
            translate([0,0,zaxis_motor_offset_z])
                mirror([i==-1?1:0,0,0])
                {
                    zaxis_motor_mount();

                    translate([zmotor_mount_rod_offset_x, 0, zmotor_mount_thickness_h/2])
                    {
                        mount_rod_clamp_half(
                                rod_d=zaxis_rod_d,
                                screw_dist=zmotor_mount_clamp_dist,
                                thick=5,
                                base_thick=5,
                                width=zmotor_mount_thickness_h,
                                thread=zmotor_mount_clamp_thread);
                    }

                    attach([[lookup(NemaSideSize,zaxis_motor)/2,0,0],[0,0,0]],zmotor_mount_conn_motor)
                    {
                        // z motor/leadscrews
                        motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
                    }
                }

            // z smooth rods
            translate([i*(lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            translate([i*(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
            {
                // z rods
                translate([0,0,zaxis_motor_offset_z-50])
                    fncylindera(h=zaxis_rod_l,d=zaxis_rod_d, align=[0,0,1]);

                for(j=[-1,1])
                    translate([0,0,axis_pos_z-j*xaxis_rod_distance/2])
                        bearing(zaxis_bearing);

            }

            translate([i*zmotor_mount_rod_offset_x, 0, axis_pos_z])
                #fncylindera(h=100, d=zaxis_nut[1], align=[0,0,0]);

            translate([i*zaxis_leadscrew_offset_x, 0, axis_pos_z-xaxis_rod_distance/2-10])
            {
                difference()
                {
                    #fncylindera(h=10, d=zaxis_nut[1], align=[0,0,0]);
                    union()
                    {
                        fncylindera(h=10+1, d=zaxis_nut[0], center= false);
                        translate([0, 13.5, -1]) fncylindera(h=5, r=1.6);
                        translate([0, -13.5, -1]) fncylindera(h=5, r=1.6);
                    }
                }
            }
        }
    }

    for(x=[-1,1])
    translate([x*(main_width/2-extrusion_size),main_depth/2,-main_lower_dist_z-extrusion_size])
    {
        translate([-x*psu_w/2, -psu_d/2, psu_h/2])
        {
            psu();

            mirror([x==-1?1:0,0,0])
            translate([0, -psu_screw_dist_y/2, 0])
                psu_extrusion_bracket_side();

            translate([0, psu_screw_dist_y/2, 0])
                psu_extrusion_bracket_back();
        }
    }
}

module upper_gantry_zrod_connector()
{
    upper_width_extra = main_upper_width-main_width;
    difference()
    {
        union()
        {
            hull()
            {
                // attach to z rod
                translate([lookup(NemaSideSize,zaxis_motor)/2, 0, 0])
                translate([(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
                {
                    cubea([gantry_connector_thickness, zmotor_mount_clamp_width, extrusion_size+gantry_connector_thickness], align=[-1,0,1]);
                }

                // connect upper gantry
                translate([upper_width_extra/2, 0, 0])
                    translate([0,0,extrusion_size/2])
                    cubea([gantry_connector_thickness,main_upper_dist_y+extrusion_size,extrusion_size], align=[1,0,0], extrasize=[0,0,gantry_connector_thickness], extrasize_align=[0,0,1]);
            }

            translate([upper_width_extra/2, 0, 0])
                translate([0,0,extrusion_size])
                cubea([extrusion_size*1.5,main_upper_dist_y+extrusion_size,gantry_connector_thickness], align=[-1,0,1]);

        }

        // cut out z rod mounting clamp nut traps and screw holes
        translate([0,0,extrusion_size/2])
        translate([upper_width_extra/2, 0, 0])
        for(i=[-1,1])
        {
            translate([-1, i*zmotor_mount_clamp_dist/2, 0])
            {
                fncylindera(fn=6, d=zmotor_mount_clamp_nut_dia, h=zmotor_mount_clamp_nut_thick, orient=[1,0,0], align=[1,0,0]);

                fncylindera(d=zmotor_mount_clamp_thread_dia, h=100, orient=[1,0,0], align=[1,0,0]);
            }
        }

        // cutout for z rod
        translate([lookup(NemaSideSize,zaxis_motor)/2, 0, 0])
        translate([(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,extrusion_size])
        fncylindera(d=zaxis_rod_d*1.01, h=extrusion_size*3, align=[0,0,0], orient=[0,0,1]);
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    {
        if(preview_mode)
        {
            cubea(size=[extrusion_size, extrusion_size, main_height], align=[-i,0,1]);
        }
        else
        {
            linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);
        }
    }

    translate([0, 0, main_height])
    {
        if(preview_mode)
        {
            cubea(size=[main_upper_width, extrusion_size, extrusion_size], align=[0,0,1]);
        }
        else
        {
            linear_extrusion(h=main_upper_width, align=[0,0,1], orient=[1,0,0]);
        }
    }
}

module gantry_lower()
{
    for(i=[-1,1])
    translate([0,  i*(main_depth/2), 0])
    {
        if(preview_mode)
        {
            cubea([main_width, extrusion_size, extrusion_size], align=[0,i,-1]);
        }
        else
        {
            linear_extrusion(h=main_width, align=[0,i,-1], orient=[1,0,0]);
        }
    }

    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    {
        if(preview_mode)
        {
            cubea([extrusion_size, main_depth, extrusion_size], align=[-i,0,-1]);
        }
        else
        {
            linear_extrusion(h=main_depth, align=[-i,0,-1], orient=[0,1,0]);
        }
    }
}

module enclosure()
{
    w=60*cm;
    h=60*cm;
    d=60*cm;
    wallthick=2*cm;
    backthick=0.5*cm;

    translate([0, 0, h/2])
    {
        // left/right walls
        for(i=[-1,1])
            translate([i*w/2,0,0])
                cubea([wallthick,d,h], align=[-i, 0, 0]);

        // back plate
        translate([0,d/2,0])
            cubea([w,backthick,h], align=[0,-1, 0]);

        // top/bottom plate
        for(i=[-1,1])
        translate([0,0,i*h/2])
            cubea([w-wallthick*2,d,wallthick], align=[0,0, -i]);
    }
}

translate([0, 0, main_lower_dist_z+extrusion_size*2])
main();

/*psu();*/

/*%enclosure();*/

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>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;
include <thing_libutils/timing-belts.scad>;

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>
include <misc.scad>
include <extruder-direct.scad>
include <x-carriage.scad>
include <y-axis.scad>
include <z-axis.scad>
include <psu.scad>
include <rod-clamps.scad>

use <scad-utils/trajectory.scad>
use <scad-utils/trajectory_path.scad>
use <scad-utils/transformations.scad>
use <scad-utils/shapes.scad>
use <list-comprehension-demos/skin.scad>

axis_pos_x = 0*mm;
axis_range_z=[85,380];
axis_pos_z = axis_range_z[1]*mm/2;

module main()
{
    color(extrusion_color)
    gantry_lower();

    color(extrusion_color)
    translate([0,0,-main_lower_dist_z])
    gantry_lower();

    color(extrusion_color)
    for(i=[-1,1])
    translate([0,i*(main_upper_dist_y/2),0])
    gantry_upper();

    // x axis
    translate([0,0,axis_pos_z])
    {
        if(!preview_mode)
        {
            translate([0, xaxis_zaxis_distance_y, 0])
                belt_path(500, 6, xaxis_pulley_d, orient=[1,0,0]);
        }

        translate([axis_pos_x,0,0])
        {
            // x carriage
            attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],[0,0,0]])
            {
                x_carriage(show_bearings=true);
            }

            if(!preview_mode)
            {
                attach([[12, -30, -30], [1,0,0]], extruder_conn_xcarriage)
                {
                    extruder();
                }
            }
        }

        // x smooth rods
        for(i=[-1,1])
            translate([0,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);

        translate([16,16,-8])
            translate([(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            /*translate([(xaxis_bearing_distance+xaxis_bearing[2])/2, xaxis_zaxis_distance_y, 0])*/
            idler_x_end();

        translate([-21,16,-8])
            translate([-(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            motor_x_end();
    }

    // y axis
    attach([[0,main_depth/2,0], [0,-1,0]], yaxis_motor_mount_conn)
    {
        yaxis_motor_mount();

        attach([[0,0,0],[0,0,0]], yaxis_motor_mount_conn_motor)
        {
            motor(yaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);

            translate([0,0,5*mm])
            fncylindera(d=yaxis_pulley_d, h=10*mm, orient=[0,0,1]);
        }
    }

    translate([0,0,yaxis_bearing[0]/2])
    {
        if(!preview_mode)
        {
            belt_path(main_depth-yaxis_motor_offset*2, 6, yaxis_pulley_d, orient=[0,1,0]);
        }

        for(i=[-1,1])
        for(j=[-1,1])
        {
            attach([[i*(yaxis_rod_distance/2),j*(main_depth/2+extrusion_size/2),0],[0,0,1]],mount_rod_clamp_conn_rod)
            {
                mount_rod_clamp_full(rod_d=zaxis_rod_d, thick=4, width=extrusion_size, thread=zmotor_mount_clamp_thread, orient=[0,1,0]);
            }
        }

        for(i=[-1,1])
        translate([i*(yaxis_rod_distance/2), 0, 0])
        {
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=[0,1,0]);

            for(j=[-1,1])
            {
                attach([[0,j*(yaxis_rod_distance/2),0],[0,0,-1]], ycarriage_bearing_mount_conn_bearing)
                {
                    ycarriage_bearing_mount(show_bearing=true, show_zips=true);
                }
            }
        }

        attach([[0,0,0],[0,0,-1]], ycarriage_bearing_mount_conn_bearing)
        {
            // y axis plate
            cubea(ycarriage_size, align=[0,0,-1]);

            translate([0,0,-10*mm])
                cubea(ycarriage_size, align=[0,0,-1]);
        }
    }

    // z axis
    for(i=[-1,1])
    {
        translate([i*(main_width/2),0,main_height])
        {
            mirror([i==-1?1:0,0,0])
            {
                upper_gantry_zrod_connector();

                translate([zmotor_mount_rod_offset_x, 0, extrusion_size/2])
                    mount_rod_clamp_half(
                            rod_d=zaxis_rod_d,
                            screw_dist=zmotor_mount_clamp_dist,
                            thick=5,
                            base_thick=5,
                            width=zmotor_mount_thickness_h,
                            thread=zmotor_mount_clamp_thread);
            }
        }

        translate([i*(main_width/2), 0, 0])
        {
            translate([0,0,zaxis_motor_offset_z])
                mirror([i==-1?1:0,0,0])
                {
                    zaxis_motor_mount();

                    translate([zmotor_mount_rod_offset_x, 0, zmotor_mount_thickness_h/2])
                    {
                        mount_rod_clamp_half(
                                rod_d=zaxis_rod_d,
                                screw_dist=zmotor_mount_clamp_dist,
                                thick=5,
                                base_thick=5,
                                width=zmotor_mount_thickness_h,
                                thread=zmotor_mount_clamp_thread);
                    }

                    attach([[lookup(NemaSideSize,zaxis_motor)/2,0,0],[0,0,0]],zmotor_mount_conn_motor)
                    {
                        // z motor/leadscrews
                        motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
                    }
                }

            // z smooth rods
            translate([i*(lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
            translate([i*(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
            {
                // z rods
                translate([0,0,zaxis_motor_offset_z-50])
                    fncylindera(h=zaxis_rod_l,d=zaxis_rod_d, align=[0,0,1]);

                for(j=[-1,1])
                    translate([0,0,axis_pos_z-j*xaxis_rod_distance/2])
                        bearing(zaxis_bearing);

            }

            translate([i*zmotor_mount_rod_offset_x, 0, axis_pos_z])
                #fncylindera(h=100, d=zaxis_nut[1], align=[0,0,0]);

            translate([i*zaxis_leadscrew_offset_x, 0, axis_pos_z-xaxis_rod_distance/2-10])
            {
                difference()
                {
                    #fncylindera(h=10, d=zaxis_nut[1], align=[0,0,0]);
                    union()
                    {
                        fncylindera(h=10+1, d=zaxis_nut[0], center= false);
                        translate([0, 13.5, -1]) fncylindera(h=5, r=1.6);
                        translate([0, -13.5, -1]) fncylindera(h=5, r=1.6);
                    }
                }
            }
        }
    }

    for(x=[-1,1])
    translate([x*(main_width/2-extrusion_size),main_depth/2,-main_lower_dist_z-extrusion_size])
    {
        translate([-x*psu_w/2, -psu_d/2, psu_h/2])
        {
            psu();

            mirror([x==-1?1:0,0,0])
            translate([0, -psu_screw_dist_y/2, 0])
                psu_extrusion_bracket_side();

            translate([0, psu_screw_dist_y/2, 0])
                psu_extrusion_bracket_back();
        }
    }
}

module upper_gantry_zrod_connector()
{
    upper_width_extra = main_upper_width-main_width;
    difference()
    {
        union()
        {
            hull()
            {
                // attach to z rod
                translate([lookup(NemaSideSize,zaxis_motor)/2, 0, 0])
                translate([(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
                {
                    cubea([gantry_connector_thickness, zmotor_mount_clamp_width, extrusion_size+gantry_connector_thickness], align=[-1,0,1]);
                }

                // connect upper gantry
                translate([upper_width_extra/2, 0, 0])
                    translate([0,0,extrusion_size/2])
                    cubea([gantry_connector_thickness,main_upper_dist_y+extrusion_size,extrusion_size], align=[1,0,0], extrasize=[0,0,gantry_connector_thickness], extrasize_align=[0,0,1]);
            }

            translate([upper_width_extra/2, 0, 0])
                translate([0,0,extrusion_size])
                cubea([extrusion_size*1.5,main_upper_dist_y+extrusion_size,gantry_connector_thickness], align=[-1,0,1]);

        }

        // cut out z rod mounting clamp nut traps and screw holes
        translate([0,0,extrusion_size/2])
        translate([upper_width_extra/2, 0, 0])
        for(i=[-1,1])
        {
            translate([-1, i*zmotor_mount_clamp_dist/2, 0])
            {
                fncylindera(fn=6, d=zmotor_mount_clamp_nut_dia, h=zmotor_mount_clamp_nut_thick, orient=[1,0,0], align=[1,0,0]);

                fncylindera(d=zmotor_mount_clamp_thread_dia, h=100, orient=[1,0,0], align=[1,0,0]);
            }
        }

        // cutout for z rod
        translate([lookup(NemaSideSize,zaxis_motor)/2, 0, 0])
        translate([(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,extrusion_size])
        fncylindera(d=zaxis_rod_d*1.01, h=extrusion_size*3, align=[0,0,0], orient=[0,0,1]);
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    {
        if(preview_mode)
        {
            cubea(size=[extrusion_size, extrusion_size, main_height], align=[-i,0,1]);
        }
        else
        {
            linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);
        }
    }

    translate([0, 0, main_height])
    {
        if(preview_mode)
        {
            cubea(size=[main_upper_width, extrusion_size, extrusion_size], align=[0,0,1]);
        }
        else
        {
            linear_extrusion(h=main_upper_width, align=[0,0,1], orient=[1,0,0]);
        }
    }
}

module gantry_lower()
{
    for(i=[-1,1])
    translate([0,  i*(main_depth/2), 0])
    {
        if(preview_mode)
        {
            cubea([main_width, extrusion_size, extrusion_size], align=[0,i,-1]);
        }
        else
        {
            linear_extrusion(h=main_width, align=[0,i,-1], orient=[1,0,0]);
        }
    }

    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    {
        if(preview_mode)
        {
            cubea([extrusion_size, main_depth, extrusion_size], align=[-i,0,-1]);
        }
        else
        {
            linear_extrusion(h=main_depth, align=[-i,0,-1], orient=[0,1,0]);
        }
    }
}

module enclosure()
{
    w=60*cm;
    h=60*cm;
    d=60*cm;
    wallthick=2*cm;
    backthick=0.5*cm;

    translate([0, 0, h/2])
    {
        // left/right walls
        for(i=[-1,1])
            translate([i*w/2,0,0])
                cubea([wallthick,d,h], align=[-i, 0, 0]);

        // back plate
        translate([0,d/2,0])
            cubea([w,backthick,h], align=[0,-1, 0]);

        // top/bottom plate
        for(i=[-1,1])
        translate([0,0,i*h/2])
            cubea([w-wallthick*2,d,wallthick], align=[0,0, -i]);
    }
}

translate([0, 0, main_lower_dist_z+extrusion_size*2])
main();

/*psu();*/

/*%enclosure();*/


The outerIconTranslateY was paramterized.

use <../../external-resources/africa/africa-outline-hi.scad>
use <../../external-resources/batman/batman.scad>
use <../../external-resources/oshw/oshw-logo-800-px.scad>

use <../../shapes/balloon/balloon.scad>
use <../../shapes/blue-moon/blue-moon.scad>
use <../../shapes/clover/clover.scad>
use <../../shapes/disk/disk.scad>
use <../../shapes/heart/heart.scad>
use <../../shapes/hourglass/hourglass.scad>
use <../../shapes/horseshoe/horseshoe.scad>
use <../../shapes/oval/oval.scad>
use <../../shapes/religion/christianity/crucifixion-cross/crucifixion-cross.scad>
use <../../shapes/religion/judaism/star-of-david/star-of-david.scad>
use <../../shapes/religion/islam/crescent-star/crescent-star.scad>
use <../../shapes/spurs/spurs-a.scad>
use <../../shapes/star/star.scad>
use <../../shapes/texas/texas.scad>
use <../../shapes/throwie-cutout/throwie-cutout.scad>
use <../../shapes/trees/christmas/christmas-tree.scad>

module coin(innerIcon,
            innerIconXyScale,
            innerIconOffsetY,
            outerIcon,
            outerIconCount,
            outerIconXyScale,
			outerIconTranslateY = 43,
            radius,
            height)
{
    difference()
    {
        // main disk
        cylinder (h = height, r=radius, center = true, $fn=100);

        // inner icon
        translate([0, innerIconOffsetY, -5])
        scale([innerIconXyScale, innerIconXyScale, 16.5])
        coinIcon(innerIcon, height);

        // outer icons
        for ( i = [0 : outerIconCount] )
        {
            rotate( i * 360 / (outerIconCount+1), [0, 0, 1])
            translate([0, outerIconTranslateY, -5])
            scale([outerIconXyScale, outerIconXyScale, 13.0])
            coinIcon(outerIcon, height);
        }
    }
}

module coinIcon(iconName, height)
{
    if(iconName == "Cross")
    {
        crucifixionCcross(height);
    }
	else if(iconName == "Spur")
	{
		spur();
	}
    else if(iconName == "Throwie")
    {
        throwieCutout(height=height);
    }
    else if(iconName == "Star of David")
    {
        starOfDavid();
    }
    else if(iconName == "Crescent Star")
    {
        crescentStar();
    }
    else if(iconName == "Star")
    {
        star(height);
    }
    else if(iconName == "Blue Moon")
    {
        blueMoon();
    }
    else if(iconName == "Clover")
    {
        clover();
    }
    else if(iconName == "Heart")
    {
        heart();
    }
    else if(iconName == "Horseshoe")
    {
        horseshoe();
    }
    else if(iconName == "Hourglass")
    {
        hourglass();
    }
    else if(iconName == "OSHW")
    {
        oshwLogo();
    }
    else if(iconName == "Texas")
    {
        texas();
    }
    else if(iconName == "Africa")
    {
        africa();
    }
    else if(iconName == "Oval")
    {
        oval();
    }
    else if(iconName == "Balloon")
    {
        balloon();
    }
    else if(iconName == "Circle")
    {
        disk();
    }
    else if(iconName == "Batman")
    {
        batmanLogo();
    }
    else if(iconName == "Tree")
    {
        christmasTree(height);
    }
    else
    {
        // default is to do nothing
//        echo("no coin used");
    }
}

use <../../external-resources/africa/africa-outline-hi.scad>
use <../../external-resources/batman/batman.scad>
use <../../external-resources/oshw/oshw-logo-800-px.scad>

use <../../shapes/balloon/balloon.scad>
use <../../shapes/blue-moon/blue-moon.scad>
use <../../shapes/clover/clover.scad>
use <../../shapes/disk/disk.scad>
use <../../shapes/heart/heart.scad>
use <../../shapes/hourglass/hourglass.scad>
use <../../shapes/horseshoe/horseshoe.scad>
use <../../shapes/oval/oval.scad>
use <../../shapes/religion/christianity/crucifixion-cross/crucifixion-cross.scad>
use <../../shapes/religion/judaism/star-of-david/star-of-david.scad>
use <../../shapes/religion/islam/crescent-star/crescent-star.scad>
use <../../shapes/spurs/spurs-a.scad>
use <../../shapes/star/star.scad>
use <../../shapes/texas/texas.scad>
use <../../shapes/throwie-cutout/throwie-cutout.scad>
use <../../shapes/trees/christmas/christmas-tree.scad>

module coin(innerIcon,
            innerIconXyScale,
            innerIconOffsetY,
            outerIcon,
            outerIconCount,
            outerIconXyScale,
            radius,
            height)
{
    difference()
    {
        // main disk
        cylinder (h = height, r=radius, center = true, $fn=100);

        // inner icon
        translate([0, innerIconOffsetY, -5])
        scale([innerIconXyScale, innerIconXyScale, 16.5])
        coinIcon(innerIcon, height);

        // outer icons
        for ( i = [0 : outerIconCount] )
        {
            rotate( i * 360 / (outerIconCount+1), [0, 0, 1])
            translate([0, 43, -5])
            scale([outerIconXyScale, outerIconXyScale, 13.0])
            coinIcon(outerIcon, height);
        }
    }
}

module coinIcon(iconName, height)
{
    if(iconName == "Cross")
    {
        crucifixionCcross(height);
    }
	else if(iconName == "Spur")
	{
		spur();
	}
    else if(iconName == "Throwie")
    {
        throwieCutout(height=height);
    }
    else if(iconName == "Star of David")
    {
        starOfDavid();
    }
    else if(iconName == "Crescent Star")
    {
        crescentStar();
    }
    else if(iconName == "Star")
    {
        star(height);
    }
    else if(iconName == "Blue Moon")
    {
        blueMoon();
    }
    else if(iconName == "Clover")
    {
        clover();
    }
    else if(iconName == "Heart")
    {
        heart();
    }
    else if(iconName == "Horseshoe")
    {
        horseshoe();
    }
    else if(iconName == "Hourglass")
    {
        hourglass();
    }
    else if(iconName == "OSHW")
    {
        oshwLogo();
    }
    else if(iconName == "Texas")
    {
        texas();
    }
    else if(iconName == "Africa")
    {
        africa();
    }
    else if(iconName == "Oval")
    {
        oval();
    }
    else if(iconName == "Balloon")
    {
        balloon();
    }
    else if(iconName == "Circle")
    {
        disk();
    }
    else if(iconName == "Batman")
    {
        batmanLogo();
    }
    else if(iconName == "Tree")
    {
        christmasTree(height);
    }
    else
    {
        // default is to do nothing
//        echo("no coin used");
    }
}


added cable guide hole and screw holes

added cable guide hole and screw holes

use <lcd.scad>
use <menu_knob.scad>
use <menu_knob_manipulator.scad>
use <reset_button.scad>
use <sdcard_reader.scad>
use <cable_guide.scad>

boxSize = [143, 148, 6+7];
lcdOffset = boxSize - [98+5, 60+5, 12];
encoderOffset = [20-14/2, boxSize[1]-30/2-15/2-3, boxSize[2]-(6+7)];
sdCardOffset = [35, 80, boxSize[2]-6];
resetButtonOffset = [encoderOffset[0]+14/2, 68, 1];

//rotate([180, 0, 0])
{
  difference()
  {
    union()
    {
      // main mounting legs
      for(offset = [ [boxSize[0]-16, 0, boxSize[2]-7], [boxSize[0]-70, 0, boxSize[2]-7] ])
        translate(offset)
          cube([16, 40+13, 7]);
      // side mounting wing
      translate([15, 0, 6])
        cube([18, 20, 7]);

      difference()
      {
        // main working area
        cube(boxSize);
        // prusa's framework  corner
        translate([15, 0, 0])
          cube([143-15, 53, boxSize[2]]);
        // LCD
        translate(lcdOffset)
          lcdBoard();
        // encoder
        translate(encoderOffset)
          menuKnob();
        // SD card mount
        translate(sdCardOffset)
          rotate([0,180,0])
            sdCardReader();
        // reset button
        translate(resetButtonOffset)
          resetButton();
        // cable guide drill
        translate([boxSize[0]-75-5, 40+16+10, 0])
          cableGuide();
        // side mounting wing cut-in, so that screw will hold tight
          cube([15, 30, 6]);
      }
    }

    // mounting drills
    for(offsetOY = [ 13/2+5/2, 40+13+5])
      for(offsetOX = [15/2, boxSize[0]-70+16/2, boxSize[0]-16/2])
        translate([offsetOX, offsetOY, 0])
          cylinder(r=5/2, h=6+7, $fs=1);
  }

  // LCD stub
  %translate(lcdOffset)
    lcdBoard();
  // encoder stub
  %translate(encoderOffset)
  {
    menuKnob();
    translate([7, 6, 23+4])
      rotate([180,0,0])
        menuKnobManipulator();
  }
  // SD card mount stub
  %translate(sdCardOffset)
    rotate([0,180,0])
      sdCardReader();
  // reset button stub
  %translate(resetButtonOffset)
    resetButton();
}

use <lcd.scad>
use <menu_knob.scad>
use <menu_knob_manipulator.scad>
use <reset_button.scad>
use <sdcard_reader.scad>

boxSize = [143, 148, 6+7];
lcdOffset = boxSize - [98+5, 60+5, 12];
encoderOffset = [20-14/2, boxSize[1]-30/2-15/2-3, boxSize[2]-(6+7)];
sdCardOffset = [35, 80, boxSize[2]-6];
resetButtonOffset = [encoderOffset[0]+14/2, 68, 1];

//rotate([180, 0, 0])
{
  difference()
  {
    // main working area
    cube(boxSize);
    // prusa's framework  corner
    translate([15, 0, 0])
      cube([143-15, 53, boxSize[2]]);
    // LCD
    translate(lcdOffset)
      lcdBoard();
    // encoder
    translate(encoderOffset)
      menuKnob();
    // SD card mount
    translate(sdCardOffset)
      rotate([0,180,0])
        sdCardReader();
    // reset button
    translate(resetButtonOffset)
      resetButton();
  }

  // main mounting legs
  for(offset = [ [boxSize[0]-16, 0, boxSize[2]-7], [boxSize[0]-70, 0, boxSize[2]-7] ])
    translate(offset)
      cube([16, 40+13, 7]);
  // side mounting wing
  translate([15, 0, 6])
    cube([18, 20, 7]);

  // LCD stub
  %translate(lcdOffset)
    lcdBoard();
  // encoder stub
  %translate(encoderOffset)
  {
    menuKnob();
    translate([7, 6, 23+4])
      rotate([180,0,0])
        menuKnobManipulator();
  }
  // SD card mount stub
  %translate(sdCardOffset)
    rotate([0,180,0])
      sdCardReader();
  // reset button stub
  %translate(resetButtonOffset)
    resetButton();
}


A second icon was added.

A second icon was added.

use <../../external-resources/batman/batman.scad>

use <../../shapes/heart/heart.scad>
use <../../shapes/open-cylinder/open-cylinder.scad>

module lightSignal(baseHeight = 2,
                    icon1 = "",
                    icon1_scale = 1,
                    icon1_x = 0,
                    icon1_y = 0,
                    icon2 = "",
                    icon2_scale = 1.0,
                    icon2_x = 0,
                    icon2_y = 0,
                    text1 = "",
                    text1_fontSize = 7.5,
                    text1_x = 0,
                    text1_y = 0,
                    text2 = "",
                    text2_fontSize = 7.5,
                    text2_x = 0,
                    text2_y = 0)
{
	difference()
	{
		lightSignal_shell(baseHeight, showOriginal = false);

		lightSignal_cutouts(icon1,
                                    icon1_scale,
                                    icon1_x,
                                    icon1_y,
                                    icon2,
                                    icon2_scale,
                                    icon2_x,
                                    icon2_y,
                                    text1,
                                    text1_fontSize,
                                    text1_x,
                                    text1_y,
                                    text2,
                                    text2_fontSize,
                                    text2_x,
                                    text2_y);
	}
}

/** Support functions and moduules follow. **/

// DO NOT CHANGE THE RADIUS; IT MACHES THE ORIGINAL MODEL
function lightSignal_stlBaseInnerRadius() = 18.5;

function lightSignal_stlBaseOuterRadius() = lightSignal_stlBaseInnerRadius() + 2.5;

module lightSignal_cutouts(icon1,
                            icon1_scale,
                            icon1_x,
                            icon1_y,
                            icon2,
                            icon2_scale,
                            icon2_x,
                            icon2_y,
                            text1,
                            text1_fontSize,
                            text1_x,
                            text1_y,
                            text2,
                            text2_fontSize,
                            text2_x,
                            text2_y)
{
		lightSignal_textCutouts(text1,
                                        text1_fontSize,
                                        text1_x,
                                        text1_y,
                                        text2,
                                        text2_fontSize,
                                        text2_x,
                                        text2_y);

		lightSignal_iconCutouts(icon1,
                                        icon1_scale,
                                        icon1_x,
                                        icon1_y,
                                        icon2,
                                        icon2_scale,
                                        icon2_x,
                                        icon2_y);
}

module lightSignal_iconCutouts(icon1,
                                icon1_scale,
                                icon1_x,
                                icon1_y,
                                icon2,
                                icon2_scale,
                                icon2_x,
                                icon2_y)
{
    lightSignal_oneIconCutout(icon1,
                                icon1_scale,
                                icon1_x,
                                icon1_y);

    lightSignal_oneIconCutout(icon2,
                                icon2_scale,
                                icon2_x,
                                icon2_y);
}

module lightSignal_oneIconCutout(
                    icon1,
                    icon1_scale,
                    icon1_x,
                    icon1_y)
{
    if(icon1 == "")
    {
        // do nothing
    }
    else
    {
        zScale = 3;
        translate([icon1_x, icon1_y, -1.01])
        if(icon1 == "heart")
        {
                scale([icon1_scale, icon1_scale, zScale])
                heartThumbnail();
        }
        else if(icon1 == "bat")
        {
                scale([icon1_scale, icon1_scale, zScale])
                batmanLogoThumbnail();
        }
    }
}

module lightSignal_oneTextCutout(text, fontSize, x, y)
{
    if(text == "")
    {
        // do nothing
    }
    else
    {
        extrudeHeight = 6;
        zTranslate = -3;
        fontName = "Bauhaus 93:style=Regular";

        translate([x, y, zTranslate])
        linear_extrude(height = extrudeHeight)
        text(text = text, font = fontName, size = fontSize);
    }
}

module lightSignal_shell(baseHeight,
                        showOriginal = false)
{
	signalStl = "../../../../../../../../../../../../Versioning/world/beto-land-world/3d-printing/super-heroes/batman/bat-signal/customizable_phone_bat_signal_20150130-9347-hv0ikc-0.stl";

	stlBaseInnerRadius = lightSignal_stlBaseInnerRadius();
	stlBaseOuterRadius = lightSignal_stlBaseOuterRadius();

	union()
	{
		// this is the top hole/cutout
		zTopHoleTranslate = 35;
		color("blue")
		translate([0, 0, zTopHoleTranslate])
		openCylinder(height=1, outerRadius = 12, innerRadius=6);

		// connector for the shaft and top hole
		color("pink")
		translate([0, 0, zTopHoleTranslate-3])
		openCylinder(height=3.1, outerRadius = 19, innerRadius=8);

		// this is the bottom wide shaft
		zTranslate = -baseHeight / 2.0;
		color("orange")
		translate([0, 0, zTranslate])
		openCylinder(height=zTopHoleTranslate, outerRadius = stlBaseOuterRadius, innerRadius = stlBaseInnerRadius);

		// this thing was modeld after this original
		if(showOriginal)
		{
			color("yellow")
			translate([0, 0, zTranslate])
			import(signalStl);
		}

		// This is the bottom disk, that holds the text/icon cutout.
		color("green")
		cylinder(r=stlBaseInnerRadius+0.1, h=baseHeight, center=true);
	}
}

module lightSignal_textCutouts(text1,
                                text1_fontSize,
                                text1_x,
                                text1_y,
                                text2,
                                text2_fontSize,
                                text2_x,
                                text2_y)
{
    lightSignal_oneTextCutout(text1, text1_fontSize, text1_x, text1_y);

    lightSignal_oneTextCutout(text2, text2_fontSize, text2_x, text2_y);
}

use <../../external-resources/batman/batman.scad>

use <../../shapes/heart/heart.scad>
use <../../shapes/open-cylinder/open-cylinder.scad>

module lightSignal(baseHeight = 2,
                    icon1 = "",
                    icon1_scale = 1,
                    icon1_x = 0,
                    icon1_y = 0,
                    text1 = "",
                    text1_fontSize = 7.5,
                    text1_x = 0,
                    text1_y = 0,
                    text2 = "",
                    text2_fontSize = 7.5,
                    text2_x = 0,
                    text2_y = 0)
{
	difference()
	{
		lightSignal_shell(baseHeight, showOriginal = false);

		lightSignal_cutouts(icon1,
                                    icon1_scale,
                                    icon1_x,
                                    icon1_y,
                                    text1,
                                    text1_fontSize,
                                    text1_x,
                                    text1_y,
                                    text2,
                                    text2_fontSize,
                                    text2_x,
                                    text2_y);
	}
}

/** Support functions and moduules follow. **/

// DO NOT CHANGE THE RADIUS; IT MACHES THE ORIGINAL MODEL
function lightSignal_stlBaseInnerRadius() = 18.5;

function lightSignal_stlBaseOuterRadius() = lightSignal_stlBaseInnerRadius() + 2.5;

module lightSignal_cutouts(icon1,
                            icon1_scale,
                            icon1_x,
                            icon1_y,
                            text1,
                            text1_fontSize,
                            text1_x,
                            text1_y,
                            text2,
                            text2_fontSize,
                            text2_x,
                            text2_y)
{
		lightSignal_textCutouts(text1,
                                        text1_fontSize,
                                        text1_x,
                                        text1_y,
                                        text2,
                                        text2_fontSize,
                                        text2_x,
                                        text2_y);

		lightSignal_iconCutouts(icon1, icon1_scale, icon1_x,
		icon1_y);
}

module lightSignal_iconCutouts(icon1,
                                icon1_scale,
                                icon1_x,
                                icon1_y)
{
	if(icon1 == "")
	{
		// do nothing
	}
	else
	{
		zScale = 3;
		translate([icon1_x, icon1_y, -1.01])
		if(icon1 == "heart")
		{
			scale([icon1_scale, icon1_scale, zScale])
			heartThumbnail();
		}
		else if(icon1 == "bat")
		{
			scale([icon1_scale, icon1_scale, zScale])
			batmanLogoThumbnail();
		}
	}
}

module lightSignal_oneTextCutout(text, fontSize, x, y)
{
	if(text == "")
	{
		// do nothing
	}
	else
	{
		extrudeHeight = 6;
		zTranslate = -3;
		fontName = "Bauhaus 93:style=Regular";

		translate([x, y, zTranslate])
		linear_extrude(height = extrudeHeight)
		text(text = text, font = fontName, size = fontSize);
	}
}

module lightSignal_shell(baseHeight,
                        showOriginal = false)
{
	signalStl = "../../../../../../../../../../../../Versioning/world/beto-land-world/3d-printing/super-heroes/batman/bat-signal/customizable_phone_bat_signal_20150130-9347-hv0ikc-0.stl";

	stlBaseInnerRadius = lightSignal_stlBaseInnerRadius();
	stlBaseOuterRadius = lightSignal_stlBaseOuterRadius();

	union()
	{
		// this is the top hole/cutout
		zTopHoleTranslate = 35;
		color("blue")
		translate([0, 0, zTopHoleTranslate])
		openCylinder(height=1, outerRadius = 12, innerRadius=6);

		// connector for the shaft and top hole
		color("pink")
		translate([0, 0, zTopHoleTranslate-3])
		openCylinder(height=3.1, outerRadius = 19, innerRadius=8);

		// this is the bottom wide shaft
		zTranslate = -baseHeight / 2.0;
		color("orange")
		translate([0, 0, zTranslate])
		openCylinder(height=zTopHoleTranslate, outerRadius = stlBaseOuterRadius, innerRadius = stlBaseInnerRadius);

		// this thing was modeld after this original
		if(showOriginal)
		{
			color("yellow")
			translate([0, 0, zTranslate])
			import(signalStl);
		}

		// This is the bottom disk, that holds the text/icon cutout.
		color("green")
		cylinder(r=stlBaseInnerRadius+0.1, h=baseHeight, center=true);
	}
}

module lightSignal_textCutouts(text1,
								text1_fontSize,
								text1_x,
								text1_y,
							    text2,
								text2_fontSize,
							    text2_x,
							    text2_y)
{
	lightSignal_oneTextCutout(text1, text1_fontSize, text1_x, text1_y);

	lightSignal_oneTextCutout(text2, text2_fontSize, text2_x, text2_y);
}


buttons

buttons

$fn = 50;
button_h = 13;
overlap = 5;
total_height = 20;
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 + 2;

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 = 21;
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);
  }
}