x/end: WIP start to use new linear_bearing

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

include <config.scad>
include <thing_libutils/misc.scad>
include <thing_libutils/bearing.scad>
use <thing_libutils/screws.scad>
use <thing_libutils/timing-belts.scad>

include <thing_libutils/bearing-linear-data.scad>
use <thing_libutils/bearing-linear.scad>

motor_mount_wall_thick = xaxis_pulley[1] - xaxis_pulley[0]/2 + 4*mm;
xaxis_end_pulley_offset = 41*mm;
xaxis_end_motorsize = lookup(NemaSideSize,xaxis_motor);
xaxis_end_motor_offset=[xaxis_end_motorsize/2+zaxis_bearing[1]/2+1*mm,motor_mount_wall_thick-2*mm,0];
xaxis_end_wz = xaxis_rod_distance+xaxis_rod_d+10*mm;

xaxis_endstop_size_switch = [10.3*mm, 20*mm, 6.3*mm];
xaxis_endstop_screw_offset_switch = [-2.45*mm, 0*mm, 0*mm];

xaxis_endstop_size_SN04 = [34.15*mm, 18.15*mm, 17.8*mm];
xaxis_endstop_screw_offset_SN04 = [-27.5*mm, 0*mm, 0*mm];
xaxis_endstop_offset_SN04 = [-3*mm, 0*mm, 0*mm];

xaxis_z_bearing_mount_dir = X;

function xaxis_end_width(with_motor) = with_motor? xaxis_end_motorsize+xaxis_end_motor_offset[0] - xaxis_end_motorsize/2 : zaxis_bearing[1]/2+zaxis_nut[1];

module xaxis_end_body(part, with_motor, beltpath_index=0, nut_top=false, with_xrod_adjustment=false)
{
    nut_h = zaxis_nut[4];
    bearing_sizey = zaxis_bearing[1] + 5*mm;

    xaxis_end_xrod_offset_z = xaxis_rod_l/2 - (main_width/2 + zmotor_mount_rod_offset_x);
    xaxis_rod_d_support = xaxis_rod_d+5*mm;
    xaxis_rod_l_support = xaxis_end_xrod_offset_z + 8*mm + (with_xrod_adjustment?8*mm:0);

    if(part==undef)
    {
        difference()
        {
            xaxis_end_body(part="pos", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
            xaxis_end_body(part="neg", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
        }
        %xaxis_end_body(part="vit", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
    }
    else if(part=="pos")
    {
        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);
            for(x=[-1,1])
            for(z=[-1,1])
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                translate([x*screw_dist/2, 0, z*screw_dist/2])
                cylindera(d=lookup(ThreadSize,xaxis_motor_thread)+4*mm, h=motor_mount_wall_thick, orient=Y, align=[0,-1,0], rounding_radius=2);
            }
        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        {
            // main nut support
            rcylindera(h=zaxis_nut[4], d=zaxis_nut[0]+5*mm, align=Z);

            // nut screw holes support
            rotate(Z*90)
            for(x=[-1,1])
            translate([x*zaxis_nut[5], 0, 0])
            rcylindera(h=zaxis_nut[4], d=lookup(ThreadSize, zaxis_nut[6])+5*mm, align=Z);

            // lead screw
            // ensure some support for the leadscrew cutout all the way to the top
            /*rcylindera(h=xaxis_end_wz, d=zaxis_nut[2]*2, align=Z);*/
        }

        // x axis rod holders
        for(z=[-1,1])
        translate([0,0,z*(xaxis_rod_distance/2)])
        rcylindera(h=xaxis_rod_l_support, d=xaxis_rod_d_support, orient=X, align=[-1,0,0]);

        // endstops mount support
        /*if(xaxis_endstop_type == "SWITCH")*/
        {
            translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
            {
                rcubea(xaxis_endstop_size_switch, align=-XAXIS-ZAXIS);
            }
        }
        /*else if(xaxis_endstop_type == "SN04")*/
        {
            translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
            {
                translate(xaxis_endstop_offset_SN04)
                rcubea(xaxis_endstop_size_SN04, align=-XAXIS-ZAXIS);
            }
        }

        // z axis bearing support
        translate([0, -xaxis_zaxis_distance_y, 0])
        {
            d=bearing_sizey+4*mm;
            h=xaxis_end_wz;
            intersection()
            {
                rcylindera(h=h, d=d, orient=Z, align=N);
                rcubea(size=[d,d,h], orient=Z, align=xaxis_z_bearing_mount_dir);
            }
        }

        // belt idler screw cut support
        for(z=[-1,1])
        for(y=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0,y*-xaxis_beltpath_width/2,0])
            cylindera(orient=Y, d=15*mm, h=7*mm, align=-y*Y);
        }
    }
    else if(part=="neg")
    {
        // cut support around z axis bearings
        translate([0, -xaxis_zaxis_distance_y, 0])
        translate([0,0,.1])
        {
            d=bearing_sizey+2*mm;
            h=xaxis_end_wz+5;
            rcubea(size=[d,d,h], orient=Z, align=-xaxis_z_bearing_mount_dir);
            /*cubea([bearing_sizey+.1, bearing_sizey+.2, xaxis_end_wz+10], orient=Z, align=[0,-1,0]);*/
        }

        // x smooth rods
        for(z=[-1,1])
        translate([0,0*mm,z*(xaxis_rod_distance/2)])
        {
            xoff = - xaxis_end_xrod_offset_z -(with_xrod_adjustment?6:0)*mm;
            translate([xoff,0,0])
            cylindera(h=abs(xoff)+xaxis_end_width(with_motor)+1,d=xaxis_rod_d+.5*mm, orient=X, align=X);

            if(with_xrod_adjustment)
            {
                translate([-xaxis_rod_l_support+5*mm,0,0])
                nut_trap_cut(nut=NutHexM4, trap_axis=Y, orient=-X, align=X);

                translate([-xaxis_rod_l_support-7*mm,0,0])
                cylindera(d=10, h=10, orient=X);
            }
        }
    }
    else if(part=="vit")
    {
    }
}

module xaxis_end(part, with_motor=false, stop_x_rods=true, beltpath_index=0, show_motor=false, nut_top=false, show_nut=false, show_rods=false, show_bearings=false, with_xrod_adjustment=false)
{
    nut_h = zaxis_nut[4];
    extrasize = with_motor?0*mm:0*mm;
    extrasize_align = 1;

    if(part==undef)
    {
        difference()
        {
            xaxis_end(part="pos", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
            xaxis_end(part="neg", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
        }
        %xaxis_end(part="vit", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
    }
    else if(part=="pos")
    {
        hull()
        {
            xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

            // projection against z, ensure easy print
            translate([0,0,-xaxis_end_wz/2])
                linear_extrude(1)
                projection(cut=false)
                xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
        }
    }
    else if(part=="neg")
    {
        xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

        // belt idler screw cut
        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0, -xaxis_beltpath_width/2 - 7*mm, 0])
            {
                screw_cut(nut=NutHexM5, h=xaxis_beltpath_width+13*mm, with_nut=true, orient=Y, align=Y);
            }
        }

        //endstop mount screw cuts
        /*if(xaxis_endstop_type == "SWITCH")*/
        {
            translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
            translate(xaxis_endstop_screw_offset_switch)
            for(y=[-1,1])
            translate([-5*mm,y*9.5*mm/2,xaxis_endstop_size_switch[2]])
            {
                screw_cut(nut=NutHexM2_5, h=10*mm, embed_head=false, with_head=true, with_nut=false, orient=[0,0,-1], align=[0,0,-1]);
            }
        }
        /*else if(xaxis_endstop_type == "SN04")*/
        {
            translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
            translate(xaxis_endstop_screw_offset_SN04)
            for(y=[-1,1])
            translate([-0*mm,y*10.5*mm/2,xaxis_endstop_size_SN04[2]])
            {
                translate(xaxis_endstop_offset_SN04)
                screw_cut(nut=NutHexM3, h=20*mm, embed_head=false, with_head=true, with_nut=false, orient=[0,0,-1], align=[0,0,-1]);
            }
        }

        xaxis_end_beltpath(height=xaxis_beltpath_height_body, width=xaxis_beltpath_width);

        // z smooth bearing mounts
        for(z=[-1,1])
        {
            translate([0,0,z*(xaxis_end_wz/2-2*mm)])
            translate([0, -xaxis_zaxis_distance_y, 0])
            {
                bearing_mount_holes(
                        bearing_type=zaxis_bearing,
                        ziptie_type=ziptie_type,
                        ziptie_bearing_distance=ziptie_bearing_distance,
                        orient=Z,
                        align=[0,0,-z],
                        with_zips=true
                        );
                /*hull()*/
                /*{*/
                    /*cylindera(d=zaxis_bearing[1],h=xaxis_end_wz);*/

                    /*translate([-5*cm,0,0])*/
                    /*cylindera(d=zaxis_bearing[1],h=xaxis_end_wz);*/
                /*}*/
            }
        }

        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);

            // axle
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                round_d=1.1*lookup(NemaRoundExtrusionDiameter, xaxis_motor);
                translate([0, .1, 0])
                translate(Y)
                teardrop(d=round_d,h=motor_mount_wall_thick, tear_orient=Z, orient=Y, align=[0,-1,0], roll=90, truncate=0.9);

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

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

                for(x=[-1,1])
                for(z=[-1,1])
                translate([0,-xaxis_end_motor_offset[1],0])
                translate([x*screw_dist/2, -(xaxis_beltpath_width/2+3*mm), z*screw_dist/2])
                {
                    if(!(x==1 && z == (beltpath_index==0?1:-1)))
                    screw_cut(xaxis_motor_nut, h=25, with_nut=false, orient=Y, align=Y);
                }
            }

        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        rotate(90*Z)
        {
            union()
            {
                translate([0,0,-.1])
                {
                    // nut
                    cylindera(h=nut_h+1, d=zaxis_nut[0]*1.05, align=Z);

                    // lead screw
                    translate([0,0,-.1])
                    cylindera(h=lookup(NemaFrontAxleLength,zaxis_motor), d=zaxis_nut[2]*1.5, align=Z);

                    for(i=[-1,1])
                    translate([i*zaxis_nut[5], 0, -zaxis_nut[3]])
                    screw_cut(thread=zaxis_nut[6], h=16*mm, with_nut=false, orient=Z, align=Z);
                }
            }
        }
    }
    else if(part=="vit")
    {
        xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

        if(with_motor)
        {
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                // 1mm due to motor offset
                translate([0,-1*mm,0])
                {
                    // 1mm between pulley and motor
                    translate([0,-1*mm,0])
                    pulley(xaxis_pulley, flip=false, orient=Y, align=[0,-1,0]);

                    if(show_motor)
                    {
                        motor(xaxis_motor, NemaMedium, dualAxis=false, orientation=[-90,0,0]);
                    }
                }
            }
        }

        //endstop
        if($show_vit)
        {
            /*if(xaxis_endstop_type == "SWITCH")*/
            {
                translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
                difference()
                {
                    rcubea(xaxis_endstop_size_switch, align=[-1,0,1]);

                    translate(xaxis_endstop_screw_offset_switch)
                    for(y=[-1,1])
                    translate([-5*mm,y*9.5*mm/2,xaxis_endstop_size_switch[2]])
                    screw(nut=NutHexM2_5, with_nut=false, h=10*mm, orient=[0,0,-1], align=[0,0,-1]);
                }
            }
            /*else if(xaxis_endstop_type == "SN04")*/
            {
                translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
                translate(xaxis_endstop_offset_SN04)
                translate([-36,-9,0])
                rotate(ZAXIS*-90)
                import("stl/SN04-N_Inductive_Proximity_Sensor_3528_0.stl");
            }
        }

        // belt idler pulley screw
        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0, -xaxis_beltpath_width/2 - 7*mm, 0])
            {
                screw(nut=NutHexM5, h=25*mm, with_nut=true, orient=Y, align=Y);
            }
        }

        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            pulley(xaxis_idler_pulley, orient=Y);
        }

        if(show_nut)
        {
            mirror([0,0,nut_top?1:0])
            translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2-zaxis_nut[3]])
            xaxis_end_znut();
        }

        if(show_rods)
        {
            for(z=[-1,1])
                translate([0,0,z*xaxis_rod_distance/2])
                translate([0, -xaxis_zaxis_distance_y, 0])
                cylindera(d=zaxis_rod_d, h=zaxis_rod_l, orient=Z);
        }

        if(show_bearings)
        {
            /*for(z=[-1,1])*/
            /*translate([0,0,z*xaxis_rod_distance/2])*/
            /*translate([0, -xaxis_zaxis_distance_y, 0])*/
            /*bearing(zaxis_bearing);*/

            translate([0, -xaxis_zaxis_distance_y, 0])
            translate(-Z*xaxis_end_wz/2)
            {
                linear_bearing(bearing=LinearBearingLMH12L, align=Z, offset_flange=true);
            }
        }
    }
}

module xaxis_end_beltpath(height, width, length = 1000, align=N, orient=X)
{
    hull()
    for(z=[-1,1])
    translate([0,0,z*height/2])
    teardrop(h=length, d=width, orient=orient, align=align, roll=-180*min(0,z), truncate=1);
}

module xaxis_end_znut()
{
    difference()
    {
        union()
        {
            cylindera(d=zaxis_nut[1], h=zaxis_nut[3], orient=Z, align=Z);
            cylindera(d=zaxis_nut[0], h=zaxis_nut[4], orient=Z, align=Z);
        }

        translate([0,0,-.1])
        cylindera(d=zaxis_nut[2], h=zaxis_nut[4]+.2, orient=Z, align=Z);
    }
}

if(false)
{
    // x axis
    /*translate([0,0,axis_pos_z])*/
    {
        /*if(!$preview_mode)*/
        {
            zrod_offset = zmotor_mount_rod_offset_x;
            for(x=[-1,1])
            {
                z=xaxis_beltpath_z_offsets[x<0?0:x];
                xo = x>0?xaxis_end_pulley_offset:xaxis_end_motor_offset[0];
                xw = x<0?xaxis_end_pulley_offset:xaxis_end_motor_offset[0];
                translate([-main_width/2-xo/2, xaxis_zaxis_distance_y, z])
                rotate([90,0,0])
                color("black")
                belt_path(main_width+xw, 6, xaxis_pulley_inner_d, orient=X, align=X);
            }
        }

        /*translate([axis_pos_x,0,0])*/
        /*{*/
            // x carriage
            /*attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],N])*/
            /*{*/
                /*x_carriage_full();*/
            /*}*/
        /*}*/

        // x smooth rods
        color(color_rods)
        for(z=[-1,1])
        translate([xaxis_rod_offset_x,xaxis_zaxis_distance_y,z*(xaxis_rod_distance/2)])
        cylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=X);

        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        translate([x*(zmotor_mount_rod_offset_x),0,0])
        cylindera(h=zaxis_rod_l,d=zaxis_rod_d, orient=Z, align=N);

        for(x=[-1,1])
        {
            translate([x*(main_width/2), 0, 0])
            {
                translate([0, xaxis_zaxis_distance_y, 0])
                translate([x*zmotor_mount_rod_offset_x, 0, 0])
                mirror([max(0,x),0,0])
                {
                    xaxis_end(with_motor=true, beltpath_index=max(0,x), show_nut=true, show_motor=true, show_nut=true);
                }
            }
        }
    }

}

if(false)
{
    for(x=[-1,1])
    translate([x*55,x*55,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    {
        xaxis_end(with_motor=true, beltpath_index=max(0,x), show_motor=false, show_nut=false, show_bearings=false, with_xrod_adjustment=true);
    }
}

module part_x_end_right()
{
    x=1;
    translate([0,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    xaxis_end(with_motor=true, beltpath_index=max(0,x), with_xrod_adjustment=true);
}

module part_x_end_left()
{
    x=-1;
    translate([0,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    xaxis_end(with_motor=true, beltpath_index=max(0,x), with_xrod_adjustment=true);
}

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

include <config.scad>
include <thing_libutils/misc.scad>
include <thing_libutils/bearing.scad>
use <thing_libutils/screws.scad>
use <thing_libutils/timing-belts.scad>

motor_mount_wall_thick = xaxis_pulley[1] - xaxis_pulley[0]/2 + 4*mm;
xaxis_end_pulley_offset = 41*mm;
xaxis_end_motorsize = lookup(NemaSideSize,xaxis_motor);
xaxis_end_motor_offset=[xaxis_end_motorsize/2+zaxis_bearing[1]/2+1*mm,motor_mount_wall_thick-2*mm,0];
xaxis_end_wz = xaxis_rod_distance+xaxis_rod_d+5*mm;

xaxis_endstop_size_switch = [10.3*mm, 20*mm, 6.3*mm];
xaxis_endstop_screw_offset_switch = [-2.45*mm, 0*mm, 0*mm];

xaxis_endstop_size_SN04 = [34.15*mm, 18.15*mm, 17.8*mm];
xaxis_endstop_screw_offset_SN04 = [-27.5*mm, 0*mm, 0*mm];
xaxis_endstop_offset_SN04 = [-3*mm, 0*mm, 0*mm];

xaxis_z_bearing_mount_dir = X;

function xaxis_end_width(with_motor) = with_motor? xaxis_end_motorsize+xaxis_end_motor_offset[0] - xaxis_end_motorsize/2 : zaxis_bearing[1]/2+zaxis_nut[1];

module xaxis_end_body(part, with_motor, beltpath_index=0, nut_top=false, with_xrod_adjustment=false)
{
    nut_h = zaxis_nut[4];
    bearing_sizey = zaxis_bearing[1] + 5*mm;

    xaxis_end_xrod_offset_z = xaxis_rod_l/2 - (main_width/2 + zmotor_mount_rod_offset_x);
    xaxis_rod_d_support = xaxis_rod_d+5*mm;
    xaxis_rod_l_support = xaxis_end_xrod_offset_z + 8*mm + (with_xrod_adjustment?8*mm:0);

    if(part==undef)
    {
        difference()
        {
            xaxis_end_body(part="pos", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
            xaxis_end_body(part="neg", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
        }
        %xaxis_end_body(part="vit", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
    }
    else if(part=="pos")
    {
        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);
            for(x=[-1,1])
            for(z=[-1,1])
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                translate([x*screw_dist/2, 0, z*screw_dist/2])
                cylindera(d=lookup(ThreadSize,xaxis_motor_thread)+4*mm, h=motor_mount_wall_thick, orient=Y, align=[0,-1,0], rounding_radius=2);
            }
        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        {
            // main nut support
            rcylindera(h=zaxis_nut[4], d=zaxis_nut[0]+5*mm, align=Z);

            // nut screw holes support
            for(x=[-1,1])
            translate([x*zaxis_nut[5], 0, 0])
            rcylindera(h=zaxis_nut[4], d=lookup(ThreadSize, zaxis_nut[6])+5*mm, align=Z);

            // lead screw
            // ensure some support for the leadscrew cutout all the way to the top
            /*rcylindera(h=xaxis_end_wz, d=zaxis_nut[2]*2, align=Z);*/
        }

        // x axis rod holders
        for(z=[-1,1])
        translate([0,0,z*(xaxis_rod_distance/2)])
        rcylindera(h=xaxis_rod_l_support, d=xaxis_rod_d_support, orient=X, align=[-1,0,0]);

        // endstops mount support
        /*if(xaxis_endstop_type == "SWITCH")*/
        {
            translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
            {
                rcubea(xaxis_endstop_size_switch, align=-XAXIS-ZAXIS);
            }
        }
        /*else if(xaxis_endstop_type == "SN04")*/
        {
            translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
            {
                translate(xaxis_endstop_offset_SN04)
                rcubea(xaxis_endstop_size_SN04, align=-XAXIS-ZAXIS);
            }
        }

        // support around z axis bearings
        translate([0, -xaxis_zaxis_distance_y, 0])
        {
            d=bearing_sizey+4*mm;
            h=xaxis_end_wz;
            intersection()
            {
                rcylindera(h=h, d=d, orient=Z, align=N);
                rcubea(size=[d,d,h], orient=Z, align=xaxis_z_bearing_mount_dir);
            }
        }

        // belt idler screw cut support
        for(z=[-1,1])
        for(y=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0,y*-xaxis_beltpath_width/2,0])
            cylindera(orient=Y, d=15*mm, h=7*mm, align=-y*Y);
        }
    }
    else if(part=="neg")
    {
        // cut support around z axis bearings
        translate([0, -xaxis_zaxis_distance_y, 0])
        translate([0,0,.1])
        {
            d=bearing_sizey+2*mm;
            h=xaxis_end_wz+5;
            rcubea(size=[d,d,h], orient=Z, align=-xaxis_z_bearing_mount_dir);
            /*cubea([bearing_sizey+.1, bearing_sizey+.2, xaxis_end_wz+10], orient=Z, align=[0,-1,0]);*/
        }

        // x smooth rods
        for(z=[-1,1])
        translate([0,0*mm,z*(xaxis_rod_distance/2)])
        {
            xoff = - xaxis_end_xrod_offset_z -(with_xrod_adjustment?6:0)*mm;
            translate([xoff,0,0])
            cylindera(h=abs(xoff)+xaxis_end_width(with_motor)+1,d=xaxis_rod_d+.5*mm, orient=X, align=X);

            if(with_xrod_adjustment)
            {
                translate([-xaxis_rod_l_support+5*mm,0,0])
                nut_trap_cut(nut=NutHexM4, trap_axis=Y, orient=-X, align=X);

                translate([-xaxis_rod_l_support-7*mm,0,0])
                cylindera(d=10, h=10, orient=X);
            }
        }
    }
    else if(part=="vit")
    {
    }
}

module xaxis_end(part, with_motor=false, stop_x_rods=true, beltpath_index=0, show_motor=false, nut_top=false, show_nut=false, show_rods=false, show_bearings=false, with_xrod_adjustment=false)
{
    nut_h = zaxis_nut[4];
    extrasize = with_motor?0*mm:0*mm;
    extrasize_align = 1;

    if(part==undef)
    {
        difference()
        {
            xaxis_end(part="pos", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
            xaxis_end(part="neg", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
        }
        %xaxis_end(part="vit", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
    }
    else if(part=="pos")
    {
        hull()
        {
            xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

            // projection against z, ensure easy print
            translate([0,0,-xaxis_end_wz/2])
                linear_extrude(1)
                projection(cut=false)
                xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
        }
    }
    else if(part=="neg")
    {
        xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

        // belt idler screw cut
        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0, -xaxis_beltpath_width/2 - 7*mm, 0])
            {
                screw_cut(nut=NutHexM5, h=xaxis_beltpath_width+13*mm, with_nut=true, orient=Y, align=Y);
            }
        }

        //endstop mount screw cuts
        /*if(xaxis_endstop_type == "SWITCH")*/
        {
            translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
            translate(xaxis_endstop_screw_offset_switch)
            for(y=[-1,1])
            translate([-5*mm,y*9.5*mm/2,xaxis_endstop_size_switch[2]])
            {
                screw_cut(nut=NutHexM2_5, h=10*mm, embed_head=false, with_head=true, with_nut=false, orient=[0,0,-1], align=[0,0,-1]);
            }
        }
        /*else if(xaxis_endstop_type == "SN04")*/
        {
            translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
            translate(xaxis_endstop_screw_offset_SN04)
            for(y=[-1,1])
            translate([-0*mm,y*10.5*mm/2,xaxis_endstop_size_SN04[2]])
            {
                translate(xaxis_endstop_offset_SN04)
                screw_cut(nut=NutHexM3, h=20*mm, embed_head=false, with_head=true, with_nut=false, orient=[0,0,-1], align=[0,0,-1]);
            }
        }

        xaxis_end_beltpath(height=xaxis_beltpath_height_body, width=xaxis_beltpath_width);

        // z smooth bearing mounts
        for(z=[-1,1])
        {
            translate([0,0,z*(xaxis_end_wz/2-2*mm)])
            translate([0, -xaxis_zaxis_distance_y, 0])
            {
                bearing_mount_holes(
                        bearing_type=zaxis_bearing,
                        ziptie_type=ziptie_type,
                        ziptie_bearing_distance=ziptie_bearing_distance,
                        orient=Z,
                        align=[0,0,-z],
                        with_zips=true
                        );
                /*hull()*/
                /*{*/
                    /*cylindera(d=zaxis_bearing[1],h=xaxis_end_wz);*/

                    /*translate([-5*cm,0,0])*/
                    /*cylindera(d=zaxis_bearing[1],h=xaxis_end_wz);*/
                /*}*/
            }
        }

        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);

            // axle
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                round_d=1.1*lookup(NemaRoundExtrusionDiameter, xaxis_motor);
                translate([0, .1, 0])
                translate(Y)
                teardrop(d=round_d,h=motor_mount_wall_thick, tear_orient=Z, orient=Y, align=[0,-1,0], roll=90, truncate=0.9);

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

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

                for(x=[-1,1])
                for(z=[-1,1])
                translate([0,-xaxis_end_motor_offset[1],0])
                translate([x*screw_dist/2, -(xaxis_beltpath_width/2+3*mm), z*screw_dist/2])
                {
                    if(!(x==1 && z == (beltpath_index==0?1:-1)))
                    screw_cut(xaxis_motor_nut, h=25, with_nut=false, orient=Y, align=Y);
                }
            }

        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        {
            union()
            {
                translate([0,0,-.1])
                {
                    // nut
                    cylindera(h=nut_h+1, d=zaxis_nut[0]*1.05, align=Z);

                    // lead screw
                    translate([0,0,-.1])
                    cylindera(h=lookup(NemaFrontAxleLength,zaxis_motor), d=zaxis_nut[2]*1.5, align=Z);

                    for(i=[-1,1])
                    translate([i*zaxis_nut[5], 0, -zaxis_nut[3]])
                    screw_cut(thread=zaxis_nut[6], h=16*mm, with_nut=false, orient=Z, align=Z);
                }
            }
        }
    }
    else if(part=="vit")
    {
        xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

        if(with_motor)
        {
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                // 1mm due to motor offset
                translate([0,-1*mm,0])
                {
                    // 1mm between pulley and motor
                    translate([0,-1*mm,0])
                    pulley(xaxis_pulley, flip=false, orient=Y, align=[0,-1,0]);

                    if(show_motor)
                    {
                        motor(xaxis_motor, NemaMedium, dualAxis=false, orientation=[-90,0,0]);
                    }
                }
            }
        }

        //endstop
        if($show_vit)
        {
            /*if(xaxis_endstop_type == "SWITCH")*/
            {
                translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
                difference()
                {
                    rcubea(xaxis_endstop_size_switch, align=[-1,0,1]);

                    translate(xaxis_endstop_screw_offset_switch)
                    for(y=[-1,1])
                    translate([-5*mm,y*9.5*mm/2,xaxis_endstop_size_switch[2]])
                    screw(nut=NutHexM2_5, with_nut=false, h=10*mm, orient=[0,0,-1], align=[0,0,-1]);
                }
            }
            /*else if(xaxis_endstop_type == "SN04")*/
            {
                translate([xaxis_end_width(with_motor),0,xaxis_end_wz/2])
                translate(xaxis_endstop_offset_SN04)
                translate([-36,-9,0])
                rotate(ZAXIS*-90)
                import("stl/SN04-N_Inductive_Proximity_Sensor_3528_0.stl");
            }
        }

        // belt idler pulley screw
        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0, -xaxis_beltpath_width/2 - 7*mm, 0])
            {
                screw(nut=NutHexM5, h=25*mm, with_nut=true, orient=Y, align=Y);
            }
        }

        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            pulley(xaxis_idler_pulley, orient=Y);
        }

        if(show_nut)
        {
            mirror([0,0,nut_top?1:0])
            translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2-zaxis_nut[3]])
            xaxis_end_znut();
        }

        if(show_rods)
        {
            for(z=[-1,1])
                translate([0,0,z*xaxis_rod_distance/2])
                translate([0, -xaxis_zaxis_distance_y, 0])
                cylindera(d=zaxis_rod_d, h=zaxis_rod_l, orient=Z);
        }

        if(show_bearings)
        {
            for(z=[-1,1])
            translate([0,0,z*xaxis_rod_distance/2])
            translate([0, -xaxis_zaxis_distance_y, 0])
            bearing(zaxis_bearing);
        }
    }
}

module xaxis_end_beltpath(height, width, length = 1000, align=N, orient=X)
{
    hull()
    for(z=[-1,1])
    translate([0,0,z*height/2])
    teardrop(h=length, d=width, orient=orient, align=align, roll=-180*min(0,z), truncate=1);
}

module xaxis_end_znut()
{
    difference()
    {
        union()
        {
            cylindera(d=zaxis_nut[1], h=zaxis_nut[3], orient=Z, align=Z);
            cylindera(d=zaxis_nut[0], h=zaxis_nut[4], orient=Z, align=Z);
        }

        translate([0,0,-.1])
        cylindera(d=zaxis_nut[2], h=zaxis_nut[4]+.2, orient=Z, align=Z);
    }
}

if(false)
{
    // x axis
    /*translate([0,0,axis_pos_z])*/
    {
        /*if(!$preview_mode)*/
        {
            zrod_offset = zmotor_mount_rod_offset_x;
            for(x=[-1,1])
            {
                z=xaxis_beltpath_z_offsets[x<0?0:x];
                xo = x>0?xaxis_end_pulley_offset:xaxis_end_motor_offset[0];
                xw = x<0?xaxis_end_pulley_offset:xaxis_end_motor_offset[0];
                translate([-main_width/2-xo/2, xaxis_zaxis_distance_y, z])
                rotate([90,0,0])
                color("black")
                belt_path(main_width+xw, 6, xaxis_pulley_inner_d, orient=X, align=X);
            }
        }

        /*translate([axis_pos_x,0,0])*/
        /*{*/
            // x carriage
            /*attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],N])*/
            /*{*/
                /*x_carriage_full();*/
            /*}*/
        /*}*/

        // x smooth rods
        color(color_rods)
        for(z=[-1,1])
        translate([xaxis_rod_offset_x,xaxis_zaxis_distance_y,z*(xaxis_rod_distance/2)])
        cylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=X);

        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        translate([x*(zmotor_mount_rod_offset_x),0,0])
        cylindera(h=zaxis_rod_l,d=zaxis_rod_d, orient=Z, align=N);

        for(x=[-1,1])
        {
            translate([x*(main_width/2), 0, 0])
            {
                translate([0, xaxis_zaxis_distance_y, 0])
                translate([x*zmotor_mount_rod_offset_x, 0, 0])
                mirror([max(0,x),0,0])
                {
                    xaxis_end(with_motor=true, beltpath_index=max(0,x), show_nut=true, show_motor=true, show_nut=true);
                }
            }
        }
    }

}

if(false)
{
    for(x=[-1,1])
    translate([x*55,x*55,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    {
        xaxis_end(with_motor=true, beltpath_index=max(0,x), show_motor=false, show_nut=false, show_bearings=false, with_xrod_adjustment=true);
    }
}

module part_x_end_right()
{
    x=1;
    translate([0,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    xaxis_end(with_motor=true, beltpath_index=max(0,x), with_xrod_adjustment=true);
}

module part_x_end_left()
{
    x=-1;
    translate([0,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    xaxis_end(with_motor=true, beltpath_index=max(0,x), with_xrod_adjustment=true);
}


This is an enclosure prototype.

This is an enclosure prototype.

error: pathspec 'OpenSCAD/library/src/main/openscad/basics/rounded-edges/rounded-cube-enclosure/rounded-cube-enclosure.scad' did not match any file(s) known to git


z-motor-mount: fix nut trap cuts for clamp

include <z-motor-mount.h>
include <thing_libutils/materials.scad>
include <thing_libutils/stepper.scad>

use <thing_libutils/attach.scad>
use <thing_libutils/shapes.scad>
use <thing_libutils/screws.scad>
use <thing_libutils/transforms.scad>
use <thing_libutils/stepper.scad>

use <rod-clamps.scad>

module zaxis_motor_mount(part)
{
    if(part==U)
    {
        difference()
        {
            zaxis_motor_mount(part="pos");
            zaxis_motor_mount(part="neg");
        }
        if($show_vit)
        zaxis_motor_mount(part="vit");
    }
    else if(part=="pos")
    material(Mat_Plastic)
    {
        // top plate
        rcubea([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])
        {
            rcubea([gantry_connector_thickness+5, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[-1,0,1]);
        }

        // reinforcement plate between motor and extrusion
        rcubea([zmotor_mount_thickness, zmotor_w+2, zmotor_h], align=X-Z, extra_size=[0,0,2], extra_align=Z);

        // top extrusion mount plate
        translate([0, 0,-extrusion_size-zaxis_motor_offset_z])
        rcubea([zmotor_mount_thickness, zmotor_mount_width, extrusion_size], align=X+Z);

        // bottom extrusion mount plate
        translate([0, 0, -main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
        rcubea([zmotor_mount_thickness, zmotor_w+2, extrusion_size], align=X+Z);

        // side triangles
        for(i=[-1,1])
        {
            translate([zmotor_mount_thickness, i*((zmotor_w/2)+zmotor_mount_thickness/2), 2])
            triangle(
                zmotor_mount_rod_offset_x-zmotor_mount_thickness,
                main_lower_dist_z+extrusion_size+zaxis_motor_offset_z+2,
                depth=zmotor_mount_thickness,
                align=[1,0,-1],
                orient=X
                );

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

        attach([[get(NemaSideSize,zaxis_motor)/2,0,0],N],zmotor_mount_conn_motor)
        motor_mount(part=part, model=zaxis_motor, thickness=zmotor_mount_thickness_h);
    }
    else if(part=="neg")
    {
        // cutout for motor cables
        translate([0,0,-30*mm])
        cubea([zmotor_mount_thickness*3, 20*mm, zmotor_h], align=-Z);

        // screw holes top
        for(y=[-1,1])
        tx(zmotor_mount_thickness)
        ty(y*(zmotor_w/2+zmotor_mount_thread_dia*3))
        tz(-extrusion_size)
        screw_cut(nut=extrusion_nut, head="button", h=12*mm, orient=-X, align=-X);

        // screw hole bottom
        for(y=[0])
        tx(zmotor_mount_thickness)
        ty(y*(zmotor_w/2+zmotor_mount_thread_dia*3))
        tz(-extrusion_size-main_lower_dist_z)
        screw_cut(nut=extrusion_nut, head="button", h=12*mm, orient=-X, align=-X);

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

        // cut out z rod mounting clamp nut traps
        for(i=[-1,1])
        translate([zmotor_mount_rod_offset_x+1, i*zmotor_mount_clamp_dist/2, zmotor_mount_thickness_h/2])
        nut_trap_cut(nut=zmotor_mount_clamp_nut, trap_h=20, cut_screw=false, trap_axis=-Z, orient=-X, align=X);

        attach([[get(NemaSideSize,zaxis_motor)/2,0,0],N],zmotor_mount_conn_motor)
        motor_mount(part=part, model=zaxis_motor, thickness=zmotor_mount_thickness_h);
    }
    else if(part=="vit")
    {
        attach([[get(NemaSideSize,zaxis_motor)/2,0,0],N],zmotor_mount_conn_motor)
        motor_mount(part=part, model=zaxis_motor, thickness=zmotor_mount_thickness_h);
    }
}

module part_z_motor_mount()
{
    rotate([0,-90,0])
    zaxis_motor_mount();
}

module part_z_motor_mount_clamp()
{
    translate([0,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);
}

if(false)
zaxis_motor_mount();

include <z-motor-mount.h>
include <thing_libutils/materials.scad>
include <thing_libutils/stepper.scad>

use <thing_libutils/attach.scad>
use <thing_libutils/shapes.scad>
use <thing_libutils/screws.scad>
use <thing_libutils/transforms.scad>
use <thing_libutils/stepper.scad>

use <rod-clamps.scad>

module zaxis_motor_mount(part)
{
    if(part==U)
    {
        difference()
        {
            zaxis_motor_mount(part="pos");
            zaxis_motor_mount(part="neg");
        }
        if($show_vit)
        zaxis_motor_mount(part="vit");
    }
    else if(part=="pos")
    material(Mat_Plastic)
    {
        // top plate
        rcubea([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])
        {
            rcubea([gantry_connector_thickness+5, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[-1,0,1]);
        }

        // reinforcement plate between motor and extrusion
        rcubea([zmotor_mount_thickness, zmotor_w+2, zmotor_h], align=X-Z, extra_size=[0,0,2], extra_align=Z);

        // top extrusion mount plate
        translate([0, 0,-extrusion_size-zaxis_motor_offset_z])
        rcubea([zmotor_mount_thickness, zmotor_mount_width, extrusion_size], align=X+Z);

        // bottom extrusion mount plate
        translate([0, 0, -main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
        rcubea([zmotor_mount_thickness, zmotor_w+2, extrusion_size], align=X+Z);

        // side triangles
        for(i=[-1,1])
        {
            translate([zmotor_mount_thickness, i*((zmotor_w/2)+zmotor_mount_thickness/2), 2])
            triangle(
                zmotor_mount_rod_offset_x-zmotor_mount_thickness,
                main_lower_dist_z+extrusion_size+zaxis_motor_offset_z+2,
                depth=zmotor_mount_thickness,
                align=[1,0,-1],
                orient=X
                );

            translate([0, i*((zmotor_w/2)+zmotor_mount_thickness/2), 2])
            cubea([zmotor_mount_thickness, zmotor_mount_thickness, zmotor_mount_h+2], align=X-Z);
        }
    }
    else if(part=="neg")
    {
        // cutout for motor cables
        translate([0,0,-30*mm])
        cubea([zmotor_mount_thickness*3, 20*mm, zmotor_h], align=-Z);

        // screw holes top
        for(y=[-1,1])
        tx(zmotor_mount_thickness)
        ty(y*(zmotor_w/2+zmotor_mount_thread_dia*3))
        tz(-extrusion_size)
        screw_cut(nut=extrusion_nut, head="button", h=12*mm, orient=-X, align=-X);

        // screw hole bottom
        for(y=[0])
        tx(zmotor_mount_thickness)
        ty(y*(zmotor_w/2+zmotor_mount_thread_dia*3))
        tz(-extrusion_size-main_lower_dist_z)
        screw_cut(nut=extrusion_nut, head="button", h=12*mm, orient=-X, align=-X);

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

        // cut out z rod mounting clamp nut traps
        for(i=[-1,1])
        {
            translate([zmotor_mount_rod_offset_x-5, i*zmotor_mount_clamp_dist/2, zmotor_mount_thickness_h/2])
            {
                nut_trap_cut(nut=zmotor_mount_clamp_nut, trap_h=10, trap_axis=-Z, orient=X, align=N);
            }
        }

    }
    else if(part=="vit")
    {
        }

    attach([[get(NemaSideSize,zaxis_motor)/2,0,0],N],zmotor_mount_conn_motor)
    motor_mount(part=part, model=zaxis_motor, thickness=zmotor_mount_thickness_h);
    }

module part_z_motor_mount()
{
    rotate([0,-90,0])
    zaxis_motor_mount();
}

module part_z_motor_mount_clamp()
{
    translate([0,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);
}

if(false)
zaxis_motor_mount();


The inlined code was updated.

The inlined code was updated.

/* [Shell] */

height = 380; // [140 : 380]

innerRadius = 20; // [30 : 40]

outerRadius = 24; // [34 : 46]

shellDecoration = "none"; // [none, bumps]

/* [Rungs] */

rungsPerLevel = 2; // [1 : 4]

stepRadius = 1; // [1 : 5]

zDistanceBetweenRungs = 5; // [1:150]

zRotateAngle = 25; // [5 : 180]

/* [Endcap] */

generateEndcap = true; // [false:true]

/* [Hidden] */

i = 3; // [1:100]

rainmaker(height = height,
          outerRadius = outerRadius,
          innerRadius = innerRadius,
		  rungsPerLevel = rungsPerLevel,
		  shellDecoration = shellDecoration,
	  	  stepRadius = stepRadius,
	  	  zDistanceBetweenRungs = zDistanceBetweenRungs,
	  	  zRotateAngle = zRotateAngle);

if(generateEndcap)
{
	xTranslate = outerRadius * 2 + 10;

	endcapHeight = 6;

	endcapOuterRadius = outerRadius + 4;

	translate([xTranslate, 0, 0])
	endcap(height = endcapHeight,
			innerRadius = outerRadius,
			outerRadius = endcapOuterRadius);

}

module endcap(height = 10,
				innerRadius = 20,
				outerRadius = 24,
				endThickness = 3)
{
	union()
	{
		openCylinder(innerRadius = innerRadius,
						height = height,
						outerRadius = outerRadius);

		endcap_end(height = endThickness,
					outerRadius = outerRadius);
	}
}

// support moduiles follow

module endcap_end(height, outerRadius)
{
	cylinder(h = height,
				r = outerRadius);
}

module rainmaker(height = 140,
                 innerRadius = 30,
                 outerRadius = 34,
				 rungsPerLevel = 1,
				 shellDecoration = "none",
				 showShell = "yes",
			 	 stepRadius = 2,
				 zDistanceBetweenRungs = 5,
			 	 zRotateAngle = 25)
{
    union()
    {
        // the main shell
		if(showShell == "yes")
		{
    		#
	        openCylinder(height = height,
	                     innerRadius = innerRadius,
	                     outerRadius = outerRadius);
		}

        bottomZ = 5;

        // the steps
        zStart = bottomZ;
        step_xLength = (innerRadius * 2) + 1;
        rainmaker_steps(height = height,
						outerRadius = outerRadius,
						rungsPerLevel = rungsPerLevel,
						shellDecoration = shellDecoration,
						stepRadius = stepRadius,
						step_xLength = step_xLength,
						zDistanceBetweenRungs = zDistanceBetweenRungs,
						zRotateAngle = zRotateAngle,
                        zStart = zStart);

        // the bottom
        cylinder(r=outerRadius, h=bottomZ);
    }
}

// suport modules follow

module rainmaker_steps(height,
						outerRadius,
						rungsPerLevel,
						shellDecoration,
						stepRadius,
						step_xLength,
						zDistanceBetweenRungs,
						zRotateAngle,
						zStart)
{
	zEnd = height - zDistanceBetweenRungs - stepRadius;

    for(z = [zStart : zDistanceBetweenRungs : zEnd])
    {
		xTranslate = 0;
        zTranslate = zStart + z;

		rotate([0, 0, zRotateAngle * z])
		union()
		{
			for(s = [1 : 1 : rungsPerLevel])
			{
				union()
				{
					stepColor  = s == 1 ? "yellow" :
								 s == 2 ? "green" :
								 s == 3 ? "orange" :
								 s == 4 ? "blue" :
								          "pink";

					angleDivision = 360.0 / rungsPerLevel;
				    zRotate = (angleDivision * (s-1) ) / 2;

					color(stepColor)
			        translate([xTranslate, 0, zTranslate])
					rotate([0, 90, zRotate])
			        cylinder(r = stepRadius,
								h = step_xLength,
								center = true);

					if(shellDecoration == "bumps")
					{
// The commented code below is to help debug why rotaion is not working for the bump.
// And it will be removed hopefully soon.
//						bumpsRotate = (angleDivision * s) / s;
//						bumpsRotate = zRotate / s;
						bumpsRotate = zRotate;
//						bumpsRotate = s + 30;
//						bumpsRotate = 0;

//						echo("bumps", s, bumpsRotate);

						color(stepColor)
						translate([outerRadius, 0, zTranslate])
//rotate([bumpsRotate, 0, 0])
//rotate([0, 90, bumpsRotate])
						sphere(r=3);

// this is the bump on the 'other' end
						color(stepColor)
						translate([-outerRadius, 0, zTranslate])
//						rotate([0, 90, bumpsRotate * s])
						sphere(r=3);
					}
				}
			}
		}
    }
}

// TODO: Lower this to 50.
module openCylinder(height = 3,
                    outerRadius = 7,
                    innerRadius = 4.5,
                    fn = 100)
{
    $fn = fn;

    difference()
    {
        cylinder(r=outerRadius,
                 h=height);

        translate([0, 0, -1])
        cylinder(r=innerRadius,
                 h=height+1.01);
    }
}

// TODO: Lower this to 50.
module openCylinder(height = 3,
                    outerRadius = 7,
                    innerRadius = 4.5,
                    fn = 100)
{
    $fn = fn;

    difference()
    {
        cylinder(r=outerRadius,
                 h=height);

        translate([0, 0, -1])
        cylinder(r=innerRadius,
                 h=height+1.01);
    }
}

/* [Shell] */

height = 380; // [140 : 380]

innerRadius = 20; // [30 : 40]

outerRadius = 24; // [34 : 46]

/* [Rungs] */

rungsPerLevel = 2; // [1 : 4]

stepRadius = 1; // [1 : 5]

zDistanceBetweenRungs = 5; // [1:150]

/* [Endcap] */

generateEndcap = true; // [false:true]

/* [Hidden] */

i = 3; // [1:100]

rainmaker(height = height,
          outerRadius = outerRadius,
          innerRadius = innerRadius,
		  rungsPerLevel = rungsPerLevel,
	  	  stepRadius = stepRadius,
	  	  zDistanceBetweenRungs = zDistanceBetweenRungs);

if(generateEndcap)
{
	xTranslate = outerRadius * 2 + 10;

	endcapHeight = 6;

	endcapOuterRadius = outerRadius + 4;

	translate([xTranslate, 0, 0])
	endcap(height = endcapHeight,
			innerRadius = outerRadius,
			outerRadius = endcapOuterRadius);

}

module endcap(height = 10,
				innerRadius = 20,
				outerRadius = 24,
				endThickness = 3)
{
	union()
	{
		openCylinder(innerRadius = innerRadius,
						height = height,
						outerRadius = outerRadius);

		endcap_end(height = endThickness,
					outerRadius = outerRadius);
	}
}

// support moduiles follow

module endcap_end(height, outerRadius)
{
	cylinder(h = height,
				r = outerRadius);
}

module rainmaker(height = 140,
                 innerRadius = 30,
                 outerRadius = 34,
				 rungsPerLevel = 1,
			 	 stepRadius = 2,
				 zDistanceBetweenRungs = 5,
			 	 zRotateAngle = 25)
{
    union()
    {
        // the main shell
    	%
        openCylinder(height = height,
                     innerRadius = innerRadius,
                     outerRadius = outerRadius);

        bottomZ = 5;

        // the steps
        zStart = bottomZ;
        step_xLength = (innerRadius * 2) + 1;
        rainmaker_steps(height = height,
						rungsPerLevel = rungsPerLevel,
						stepRadius = stepRadius,
						step_xLength = step_xLength,
						zDistanceBetweenRungs = zDistanceBetweenRungs,
						zRotateAngle = zRotateAngle,
                        zStart = zStart);

        // the bottom
        cylinder(r=outerRadius, h=bottomZ);
    }
}

module rainmaker_steps(height,
						rungsPerLevel,
						stepRadius,
						step_xLength,
						zDistanceBetweenRungs,
						zRotateAngle,
						zStart)
{
	zEnd = height - zDistanceBetweenRungs - stepRadius;

    for(z = [zStart : zDistanceBetweenRungs : zEnd])
    {
		xTranslate = 0;
        zTranslate = zStart + z;

		rotate([0, 0, zRotateAngle * z])
		union()
		{
			for(s = [1 : 1 : rungsPerLevel])
			{
				stepColor  = s == 1 ? "yellow" :
							 s == 2 ? "green" :
							 s == 3 ? "orange" :
							 s == 4 ? "blue" :
							          "pink";

				angleDivision = 360.0 / rungsPerLevel;
			    zRotate = (angleDivision * (s-1) ) / 2;

				color(stepColor)
		        translate([xTranslate, 0, zTranslate])
				rotate([0, 90, zRotate])
		        cylinder(r = stepRadius,
							h = step_xLength,
							center = true);
			}
		}
    }
}

// TODO: Lower this to 50.
module openCylinder(height = 3,
                    outerRadius = 7,
                    innerRadius = 4.5,
                    fn = 100)
{
    $fn = fn;

    difference()
    {
        cylinder(r=outerRadius,
                 h=height);

        translate([0, 0, -1])
        cylinder(r=innerRadius,
                 h=height+1.01);
    }
}

// TODO: Lower this to 50.
module openCylinder(height = 3,
                    outerRadius = 7,
                    innerRadius = 4.5,
                    fn = 100)
{
    $fn = fn;

    difference()
    {
        cylinder(r=outerRadius,
                 h=height);

        translate([0, 0, -1])
        cylinder(r=innerRadius,
                 h=height+1.01);
    }
}


complete module

complete module

span=172;
dia=18;
h=60+dia;
$fn=100;

module _handle_main()
{
  difference()
  {
    union()
    {
      // side blocks
      for(dx=[0, span])
        translate(dx*[1,0,0])
          cube([dia, h, dia/2]);
      // top holder
      translate([dia, h, 0])
        cube([span-dia, dia, dia/2]);
      // rounded edges
      for(dx=[0, span-dia])
        translate([dia+dx, h,0])
          cylinder(r=dia, h=dia/2);
    }
    for(dx=[0, span-3*dia])
      translate([2*dia+dx, h-dia, -1])
        cylinder(r=dia, h=dia/2+2);
  }
}

module _hole()
{
  hull()
    for(dx=[-0.5, 0.5])
      translate([dx, 0, -1])
        cylinder(r=3.8+0.5/2, h=dia/2+2, $fn=20);
}

module _handle()
{
  difference()
  {
    _handle_main();
    // left cut in
    translate([0, 0, -1])
      rotate(-45*[0, 0, 1])
        cube(dia*[1,2,1]+[0,0,2]);
    // right cut it
    translate([span+dia, 0, dia+1])
      rotate([0, 180, 45])
        cube(dia*[1,2,1]+[0,0,2]);
    // screw holes
    for(dx=[0, span])
      translate([dx+dia/2, dia, 0])
        _hole();
  }
}

_handle();
//_hole();

span=172;
dia=18;
$fn=100;

module _handle()
{
  difference()
  {
    union()
    {
      // side blocks
      for(dx=[0, span])
        translate(dx*[1,0,0])
          cube([dia, 60, dia]);
      // top holder
      translate([dia, 60, 0])
        cube([span-dia, dia, dia]);
      // rounded edges
      for(dx=[0, span-dia])
        translate([dia+dx, 60,0])
          cylinder(r=dia, h=dia);
    }
    for(dx=[0, span-3*dia])
      translate([2*dia+dx, 60-dia, -1])
        cylinder(r=dia, h=dia+2);
  }
}

_handle();


bearing/linear/mount: fixes, open cut missing etc

include <units.scad>
include <system.scad>

use <misc.scad>
use <transforms.scad>
use <shapes.scad>
use <screws.scad>
include <bearing-linear-data.scad>
include <thread-data.scad>

module linear_bearing(part, bearing, align=N, orient=Z, offset_flange=false)
{
    model = get(LinearBearingModel, bearing);
    width_x = fallback(get(LinearBearingFlangeCutDiameter, bearing),LinearBearingOuterDiameter);
    width_y = fallback(get(LinearBearingFlangeDiameter, bearing),LinearBearingOuterDiameter);

    clip_dist = get(LinearBearingClipsDistance, bearing);
    clip_groove = get(LinearBearingClipsGrooveDepth, bearing);
    clip_dia = get(LinearBearingClipsDiameter, bearing);

    flange_h = fallback(get(LinearBearingFlangeThickness, bearing),0);

    // for all kinds of flanges
    flange_d = get(LinearBearingFlangeDiameter,bearing);

    // only for square flange
    flange_side = get(LinearBearingFlangeSide,bearing);

    // only for cut flanges
    flange_d_cut = get(LinearBearingFlangeCutDiameter,bearing);

    flange_pcd = get(LinearBearingFlangePitchCircleDiameter,bearing);

    flange_screw_len=12*mm;

    flange_offset = offset_flange ? -flange_h : 0;
    h = get(LinearBearingLength,bearing);
    d = get(LinearBearingInnerDiameter, bearing);
    D = get(LinearBearingOuterDiameter, bearing);
    s = [width_x, width_y, h];
    if(part==U)
    {
        difference()
        {
            linear_bearing(part="pos", bearing=bearing, align=align, orient=orient, offset_flange=offset_flange);
            linear_bearing(part="neg", bearing=bearing, align=align, orient=orient, offset_flange=offset_flange);
        }
        %linear_bearing(part="vit", bearing=bearing, align=align, orient=orient, offset_flange=offset_flange);
    }
    else if(part=="pos")
    size_align(size=s, align=align, orient=orient)
    translate(Z*flange_offset)
    {
        cylindera(h=h, d=D, orient=Z);

        // flange
        translate(-Z*h/2)
        {
            if(flange_side != U)
            {
                // LMK
                intersection()
                {
                    rcubea(size=[flange_side, flange_side, flange_h], orient=Z, align=Z, round_r=1);

                    rcubea(size=[flange_d, flange_d, flange_h], orient=Z, align=Z, round_r=1);
                }
            }
            else if(flange_d != U)
            {
                // LMH
                if(flange_d_cut != U)
                {
                    intersection()
                    {
                        rcylindera(h=flange_h, d=flange_d, orient=Z, align=Z, round_r=1);
                        rcubea(size=[get(LinearBearingFlangeCutDiameter, bearing), flange_d, flange_h], align=Z, round_r=1);
                    }
                }
                // LMF
                else if(flange_d != U)
                {
                    rcylindera(h=flange_h, d=flange_d, orient=Z, align=Z, round_r=1);
                }
            }
        }
    }
    else if(part=="neg")
    size_align(size=s, align=align, orient=orient)
    translate(Z*flange_offset)
    {
        translate(-Z*h/2)
        {
            // inner bore cut
            cylindera(h=h, d=d, orient=Z, align=Z, extra_h=.2);

            // clips
            if(clip_dist != U)
            {
                translate(Z*h/2)
                for(z=[-1,1])
                translate(z*Z*clip_dist/2)
                hollow_cylinder(d=D-clip_groove/2+.01, thickness=clip_groove, h=clip_groove, taper=false, orient=Z, align=-z);
            }

            // flange
            if(flange_side != U)
            {
                // LMK
                // screw cut
                for(x=[-1,1])
                for(y=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d_cut != U)
            {
                // LMH
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*get(LinearBearingFlangeCutMountHoleDist, bearing)/2)
                translate(x*X*get(LinearBearingFlangeCutMountHoleDistSide, bearing)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d != U)
            {
                // LMF
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
        }
    }
}

module linear_bearing_mount(part=part, bearing, extra_h=0, override_h=U, ziptie_type=[2*mm, 3*mm], ziptie_bearing_distance=3*mm, tolerance=.1*mm, align=N, orient=Z, ziptie_dist=U, with_zips=true, offset_flange=false, mount_dir_align=X, mount_style="open")
{
    ziptie_thickness = ziptie_type[0];
    ziptie_width = ziptie_type[1]+0.6*mm;

    ziptie_dist_ = fallback(ziptie_dist, get(LinearBearingClipsDistance,bearing)/2);

    clip_dist = get(LinearBearingClipsDistance, bearing);

    h = fallback(override_h, get(LinearBearingLength,bearing)) + extra_h;
    d = get(LinearBearingInnerDiameter, bearing);
    D = get(LinearBearingOuterDiameter, bearing);

    flange_h = fallback(get(LinearBearingFlangeThickness, bearing),0);

    // for all kinds of flanges
    flange_d = get(LinearBearingFlangeDiameter,bearing);

    // only for square flange
    flange_side = get(LinearBearingFlangeSide,bearing);

    // only for cut flanges
    flange_d_cut = get(LinearBearingFlangeCutDiameter,bearing);

    flange_pcd = get(LinearBearingFlangePitchCircleDiameter,bearing);

    flange_screw_len=12*mm;
    flange_offset = offset_flange ? -flange_h : 0;

    support_wall_thickness = 2.5*mm;

    support_D=D+2*support_wall_thickness;
    support_h = h+flange_offset;
    if(part==U)
    {
        difference()
        {
            linear_bearing_mount(part="pos", bearing=bearing, extra_h=extra_h, override_h=override_h, ziptie_type=ziptie_type, ziptie_bearing_distance=ziptie_bearing_distance, tolerance=tolerance, align=align, orient=orient, ziptie_dist=ziptie_dist, with_zips=with_zips, offset_flange=offset_flange, mount_dir_align=mount_dir_align, mount_style=mount_style);
            linear_bearing_mount(part="neg", bearing=bearing, extra_h=extra_h, override_h=override_h, ziptie_type=ziptie_type, ziptie_bearing_distance=ziptie_bearing_distance, tolerance=tolerance, align=align, orient=orient, ziptie_dist=ziptie_dist, with_zips=with_zips, offset_flange=offset_flange, mount_dir_align=mount_dir_align, mount_style=mount_style);
        }
        %linear_bearing_mount(part="vit", bearing=bearing, extra_h=extra_h, override_h=override_h, ziptie_type=ziptie_type, ziptie_bearing_distance=ziptie_bearing_distance, tolerance=tolerance, align=align, orient=orient, ziptie_dist=ziptie_dist, with_zips=with_zips, offset_flange=offset_flange, mount_dir_align=mount_dir_align, mount_style=mount_style);
    }
    else if(part=="pos")
    size_align(size=[D,D,h], align=align, orient=orient)
    {
        translate(-Z*h/2)
        {
            // z axis bearing support
            if(mount_style=="open")
            {
                intersection()
                {
                    rcylindera(h=support_h, d=D, orient=Z, align=Z);
                    rcubea(size=[D,D,support_h], orient=Z, align=Z+mount_dir_align);
                }
            }
            else if(mount_style=="closed")
            {
                rcylindera(h=support_h, d=support_D, orient=Z, align=Z);
            }

            // support for clips
            if(clip_dist != U)
            {
                translate(Z*h/2)
                for(z=[-1,1])
                translate(z*Z*clip_dist/2)
                hollow_cylinder(d=D-clip_groove/2+.01, thickness=clip_groove, h=clip_groove, taper=false, orient=Z, align=-z);
            }

            // support for flange mount
            if(flange_side != U)
            {
                // LMK
                // screw cut
                for(x=[-1,1])
                for(y=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                rcylindera(d=1.5*get(LinearBearingFlangeMountingSize,bearing), h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d_cut != U)
            {
                // LMH
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*get(LinearBearingFlangeCutMountHoleDist, bearing)/2)
                translate(x*X*get(LinearBearingFlangeCutMountHoleDistSide, bearing)/2)
                rcylindera(d=1.5*get(LinearBearingFlangeMountingSize,bearing), h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d != U)
            {
                // LMF
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                rcylindera(d=1.5*get(LinearBearingFlangeMountingSize,bearing), h=flange_screw_len, orient=Z, align=Z);
            }
        }
    }
    else if(part=="neg")
    size_align(size=[D,D,h], align=align, orient=orient)
    translate(Z*flange_offset)
    translate(-Z*.001)
    {
        // Main bearing cut
        cylindera(h=h+tolerance, d=D+tolerance, orient=Z);

        if(mount_style=="open")
        {
            orient(-orient)
            rcubea(size=[1000,1000,D+.2*mm], align=mount_dir_align);

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

        // for linear rod
        cylindera(d=d+2*mm, h=1000, orient=Z);

        // flange
        translate(-Z*h/2)
        {
            if(flange_side != U)
            {
                // LMK
                intersection()
                {
                    rcubea(size=[flange_side, flange_side, flange_h], orient=Z, align=Z, round_r=1);

                    rcubea(size=[flange_d, flange_d, flange_h], orient=Z, align=Z, round_r=1);
                }
            }
            else if(flange_d != U)
            {
                // LMH
                if(flange_d_cut != U)
                {
                    intersection()
                    {
                        rcylindera(h=flange_h, d=flange_d, orient=Z, align=Z, round_r=1);
                        rcubea(size=[get(LinearBearingFlangeCutDiameter, bearing), flange_d, flange_h], align=Z, round_r=1);
                    }
                }
                // LMF
                else if(flange_d != U)
                {
                    rcylindera(h=flange_h, d=flange_d, orient=Z, align=Z, round_r=1);
                }
            }
        }

        translate(-Z*h/2)
        {
            // inner bore cut
            cylindera(h=h, d=d, orient=Z, align=Z, extra_h=.2);

            // clips
            if(clip_dist != U)
            {
                translate(Z*h/2)
                for(z=[-1,1])
                translate(z*Z*clip_dist/2)
                hollow_cylinder(d=D-clip_groove/2+.01, thickness=clip_groove, h=clip_groove, taper=false, orient=Z, align=-z);
            }

            // flange
            if(flange_side != U)
            {
                // LMK
                // screw cut
                for(x=[-1,1])
                for(y=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d_cut != U)
            {
                // LMH
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*get(LinearBearingFlangeCutMountHoleDist, bearing)/2)
                translate(x*X*get(LinearBearingFlangeCutMountHoleDistSide, bearing)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d != U)
            {
                // LMF
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
        }

    }
    else if(part=="vit")
    size_align(size=[D,D,h], align=align, orient=orient)
    translate(Z*flange_offset)
    {
        if($show_vit)
        {
            linear_bearing(bearing=bearing);

            if(mount_style=="open")
            for(z=[-1,1])
            translate([0,0,z*ziptie_dist_])
            {
                hollow_cylinder(
                    d=D+ziptie_bearing_distance+ziptie_thickness,
                    thickness = ziptie_thickness,
                    h = ziptie_width,
                    taper=false,
                    orient=Z,
                    align=-z*Z
                    );
            }
        }
    }
}

// all
if(false)
{
    v_flangewidth = v_get(AllLinearBearing,LinearBearingFlangeDiameter);
    v_dia = v_get(AllLinearBearing,LinearBearingOuterDiameter);
    v_width = vv_fallback([v_flangewidth, v_dia]);
    dist_cumsum = v_cumsum(v_width, 0);
    for(i=[0:1:len(AllLinearBearing)-1])
    {
        bearing = AllLinearBearing[i];
        dist=dist_cumsum[i];
        translate(X*dist)
        {
            linear_bearing(bearing=bearing, align=Z);
            translate((v_width[i]/2 + 3*mm)*-Y)
            rotate(-90*Z)
            text(get(LinearBearingModel, bearing), size=v_width[i]*.8, valign="center", halign="left");

            translate((v_width[i] + 10*mm)*Y)
            linear_bearing_mount(bearing=bearing, align=Z);
        }
    }
}

if(false)
{
    stack(axis=X, dist=50*mm)
    {
        linear_bearing(bearing=LinearBearingLM6, align=Z);
        linear_bearing(bearing=LinearBearingLM6L, align=Z);
        linear_bearing(bearing=LinearBearingLMF8, align=Z);
        linear_bearing(bearing=LinearBearingLMF8L, align=Z);
        linear_bearing(bearing=LinearBearingLMK8, align=Z);
        linear_bearing(bearing=LinearBearingLMK8L, align=Z);
        linear_bearing(bearing=LinearBearingLMH12L, align=Z);
        linear_bearing(bearing=LinearBearingLMH16L, align=Z);
    }
}

include <units.scad>
include <system.scad>

use <misc.scad>
use <transforms.scad>
use <shapes.scad>
use <screws.scad>
include <bearing-linear-data.scad>
include <thread-data.scad>

module linear_bearing(part, bearing, align=N, orient=Z, offset_flange=false)
{
    model = get(LinearBearingModel, bearing);
    width_x = fallback(get(LinearBearingFlangeCutDiameter, bearing),LinearBearingOuterDiameter);
    width_y = fallback(get(LinearBearingFlangeDiameter, bearing),LinearBearingOuterDiameter);

    clip_dist = get(LinearBearingClipsDistance, bearing);
    clip_groove = get(LinearBearingClipsGrooveDepth, bearing);
    clip_dia = get(LinearBearingClipsDiameter, bearing);

    flange_h = fallback(get(LinearBearingFlangeThickness, bearing),0);

    // for all kinds of flanges
    flange_d = get(LinearBearingFlangeDiameter,bearing);

    // only for square flange
    flange_side = get(LinearBearingFlangeSide,bearing);

    // only for cut flanges
    flange_d_cut = get(LinearBearingFlangeCutDiameter,bearing);

    flange_pcd = get(LinearBearingFlangePitchCircleDiameter,bearing);

    flange_screw_len=12*mm;

    flange_offset = offset_flange ? -flange_h : 0;
    h = get(LinearBearingLength,bearing);
    d = get(LinearBearingInnerDiameter, bearing);
    D = get(LinearBearingOuterDiameter, bearing);
    s = [width_x, width_y, h];
    if(part==U)
    {
        difference()
        {
            linear_bearing(part="pos", bearing=bearing, align=align, orient=orient, offset_flange=offset_flange);
            linear_bearing(part="neg", bearing=bearing, align=align, orient=orient, offset_flange=offset_flange);
        }
        %linear_bearing(part="vit", bearing=bearing, align=align, orient=orient, offset_flange=offset_flange);
    }
    else if(part=="pos")
    size_align(size=s, align=align, orient=orient)
    translate(Z*flange_offset)
    {
        cylindera(h=h, d=D, orient=Z);

        // flange
        translate(-Z*h/2)
        {
            if(flange_side != U)
            {
                // LMK
                intersection()
                {
                    rcubea(size=[flange_side, flange_side, flange_h], orient=Z, align=Z, round_r=1);

                    rcubea(size=[flange_d, flange_d, flange_h], orient=Z, align=Z, round_r=1);
                }
            }
            else if(flange_d != U)
            {
                // LMH
                if(flange_d_cut != U)
                {
                    intersection()
                    {
                        rcylindera(h=flange_h, d=flange_d, orient=Z, align=Z, round_r=1);
                        rcubea(size=[get(LinearBearingFlangeCutDiameter, bearing), flange_d, flange_h], align=Z, round_r=1);
                    }
                }
                // LMF
                else if(flange_d != U)
                {
                    rcylindera(h=flange_h, d=flange_d, orient=Z, align=Z, round_r=1);
                }
            }
        }
    }
    else if(part=="neg")
    size_align(size=s, align=align, orient=orient)
    translate(Z*flange_offset)
    {
        translate(-Z*h/2)
        {
            // inner bore cut
            cylindera(h=h, d=d, orient=Z, align=Z, extra_h=.2);

            // clips
            if(clip_dist != U)
            {
                translate(Z*h/2)
                for(z=[-1,1])
                translate(z*Z*clip_dist/2)
                hollow_cylinder(d=D-clip_groove/2+.01, thickness=clip_groove, h=clip_groove, taper=false, orient=Z, align=-z);
            }

            // flange
            if(flange_side != U)
            {
                // LMK
                // screw cut
                for(x=[-1,1])
                for(y=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d_cut != U)
            {
                // LMH
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*get(LinearBearingFlangeCutMountHoleDist, bearing)/2)
                translate(x*X*get(LinearBearingFlangeCutMountHoleDistSide, bearing)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d != U)
            {
                // LMF
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
        }
    }
}

module linear_bearing_mount(part=part, bearing, extra_h=0, override_h=U, ziptie_type=[2*mm, 3*mm], ziptie_bearing_distance=3*mm, tolerance=.1*mm, align=N, orient=Z, ziptie_dist=U, with_zips=true, offset_flange=false, mount_dir_align=X, mount_style="closed")
{
    ziptie_thickness = ziptie_type[0];
    ziptie_width = ziptie_type[1]+0.6*mm;

    ziptie_dist_ = fallback(ziptie_dist, get(LinearBearingClipsDistance,bearing)/2);

    clip_dist = get(LinearBearingClipsDistance, bearing);

    h = fallback(override_h, get(LinearBearingLength,bearing)) + extra_h;
    d = get(LinearBearingInnerDiameter, bearing);
    D = get(LinearBearingOuterDiameter, bearing);

    flange_h = fallback(get(LinearBearingFlangeThickness, bearing),0);

    // for all kinds of flanges
    flange_d = get(LinearBearingFlangeDiameter,bearing);

    // only for square flange
    flange_side = get(LinearBearingFlangeSide,bearing);

    // only for cut flanges
    flange_d_cut = get(LinearBearingFlangeCutDiameter,bearing);

    flange_pcd = get(LinearBearingFlangePitchCircleDiameter,bearing);

    flange_screw_len=12*mm;
    flange_offset = offset_flange ? -flange_h : 0;

    support_wall_thickness = 2.5*mm;
    if(part==U)
    {
        difference()
        {
            linear_bearing_mount(part="pos", bearing=bearing, extra_h=extra_h, override_h=override_h, ziptie_type=ziptie_type, ziptie_bearing_distance=ziptie_bearing_distance, tolerance=tolerance, align=align, orient=orient, ziptie_dist=ziptie_dist, with_zips=with_zips, offset_flange=offset_flange, mount_dir_align=mount_dir_align, mount_style=mount_style);
            linear_bearing_mount(part="neg", bearing=bearing, extra_h=extra_h, override_h=override_h, ziptie_type=ziptie_type, ziptie_bearing_distance=ziptie_bearing_distance, tolerance=tolerance, align=align, orient=orient, ziptie_dist=ziptie_dist, with_zips=with_zips, offset_flange=offset_flange, mount_dir_align=mount_dir_align, mount_style=mount_style);
        }
        %linear_bearing_mount(part="vit", bearing=bearing, extra_h=extra_h, override_h=override_h, ziptie_type=ziptie_type, ziptie_bearing_distance=ziptie_bearing_distance, tolerance=tolerance, align=align, orient=orient, ziptie_dist=ziptie_dist, with_zips=with_zips, offset_flange=offset_flange, mount_dir_align=mount_dir_align, mount_style=mount_style);
    }
    else if(part=="pos")
    size_align(size=[D,D,h], align=align, orient=orient)
    {
        translate(-Z*h/2)
        {
            // z axis bearing support
            if(mount_style=="open")
            {
                intersection()
                {
                    D_=D+2*support_wall_thickness;
                    h_ = h+flange_offset;
                    rcylindera(h=h_, d=D_, orient=Z, align=Z);
                    rcubea(size=[D_,D_,h_], orient=Z, align=Z+mount_dir_align);
                }
            }
            else if(mount_style=="closed")
            {
                D_=D+2*support_wall_thickness;
                h_ = h+flange_offset;
                rcylindera(h=h_, d=D_, orient=Z, align=Z);
            }

            // support for clips
            if(clip_dist != U)
            {
                translate(Z*h/2)
                for(z=[-1,1])
                translate(z*Z*clip_dist/2)
                hollow_cylinder(d=D-clip_groove/2+.01, thickness=clip_groove, h=clip_groove, taper=false, orient=Z, align=-z);
            }

            // support for flange mount
            if(flange_side != U)
            {
                // LMK
                // screw cut
                for(x=[-1,1])
                for(y=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                rcylindera(d=1.5*get(LinearBearingFlangeMountingSize,bearing), h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d_cut != U)
            {
                // LMH
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*get(LinearBearingFlangeCutMountHoleDist, bearing)/2)
                translate(x*X*get(LinearBearingFlangeCutMountHoleDistSide, bearing)/2)
                rcylindera(d=1.5*get(LinearBearingFlangeMountingSize,bearing), h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d != U)
            {
                // LMF
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                rcylindera(d=1.5*get(LinearBearingFlangeMountingSize,bearing), h=flange_screw_len, orient=Z, align=Z);
            }
        }
    }
    else if(part=="neg")
    size_align(size=[D,D,h], align=align, orient=orient)
    translate(Z*flange_offset)
    translate(-Z*.001)
    {
        // Main bearing cut
        cylindera(h=h+tolerance, d=D+tolerance, orient=Z);

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

        // for linear rod
        cylindera(d=d+2*mm, h=1000, orient=Z);

        // flange
        translate(-Z*h/2)
        {
            if(flange_side != U)
            {
                // LMK
                intersection()
                {
                    rcubea(size=[flange_side, flange_side, flange_h], orient=Z, align=Z, round_r=1);

                    rcubea(size=[flange_d, flange_d, flange_h], orient=Z, align=Z, round_r=1);
                }
            }
            else if(flange_d != U)
            {
                // LMH
                if(flange_d_cut != U)
                {
                    intersection()
                    {
                        rcylindera(h=flange_h, d=flange_d, orient=Z, align=Z, round_r=1);
                        rcubea(size=[get(LinearBearingFlangeCutDiameter, bearing), flange_d, flange_h], align=Z, round_r=1);
                    }
                }
                // LMF
                else if(flange_d != U)
                {
                    rcylindera(h=flange_h, d=flange_d, orient=Z, align=Z, round_r=1);
                }
            }
        }

        translate(-Z*h/2)
        {
            // inner bore cut
            cylindera(h=h, d=d, orient=Z, align=Z, extra_h=.2);

            // clips
            if(clip_dist != U)
            {
                translate(Z*h/2)
                for(z=[-1,1])
                translate(z*Z*clip_dist/2)
                hollow_cylinder(d=D-clip_groove/2+.01, thickness=clip_groove, h=clip_groove, taper=false, orient=Z, align=-z);
            }

            // flange
            if(flange_side != U)
            {
                // LMK
                // screw cut
                for(x=[-1,1])
                for(y=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d_cut != U)
            {
                // LMH
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*get(LinearBearingFlangeCutMountHoleDist, bearing)/2)
                translate(x*X*get(LinearBearingFlangeCutMountHoleDistSide, bearing)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
            else if(flange_d != U)
            {
                // LMF
                // screw cut
                for(y=[-1,1])
                for(x=[-1,1])
                translate(y*Y*flange_pcd/2*sqrt(2)/2)
                translate(x*X*flange_pcd/2*sqrt(2)/2)
                screw_cut(thread=ThreadM4, h=flange_screw_len, orient=Z, align=Z);
            }
        }

    }
    else if(part=="vit")
    size_align(size=[D,D,h], align=align, orient=orient)
    translate(Z*flange_offset)
    {
        if($show_vit)
        {
            linear_bearing(bearing=bearing);

            if(mount_style=="open")
            for(z=[-1,1])
            translate([0,0,z*ziptie_dist_])
            {
                hollow_cylinder(
                    d=D+ziptie_bearing_distance+ziptie_thickness,
                    thickness = ziptie_thickness,
                    h = ziptie_width,
                    taper=false,
                    orient=Z,
                    align=-z*Z
                    );
            }
        }
    }
}

// all
if(false)
{
    v_flangewidth = v_get(AllLinearBearing,LinearBearingFlangeDiameter);
    v_dia = v_get(AllLinearBearing,LinearBearingOuterDiameter);
    v_width = vv_fallback([v_flangewidth, v_dia]);
    dist_cumsum = v_cumsum(v_width, 0);
    for(i=[0:1:len(AllLinearBearing)-1])
    {
        bearing = AllLinearBearing[i];
        dist=dist_cumsum[i];
        translate(X*dist)
        {
            linear_bearing(bearing=bearing, align=Z);
            translate((v_width[i]/2 + 3*mm)*-Y)
            rotate(-90*Z)
            text(get(LinearBearingModel, bearing), size=v_width[i]*.8, valign="center", halign="left");

            translate((v_width[i] + 10*mm)*Y)
            linear_bearing_mount(bearing=bearing, align=Z);
        }
    }
}

if(false)
{
    stack(axis=X, dist=50*mm)
    {
        linear_bearing(bearing=LinearBearingLM6, align=Z);
        linear_bearing(bearing=LinearBearingLM6L, align=Z);
        linear_bearing(bearing=LinearBearingLMF8, align=Z);
        linear_bearing(bearing=LinearBearingLMF8L, align=Z);
        linear_bearing(bearing=LinearBearingLMK8, align=Z);
        linear_bearing(bearing=LinearBearingLMK8L, align=Z);
        linear_bearing(bearing=LinearBearingLMH12L, align=Z);
        linear_bearing(bearing=LinearBearingLMH16L, align=Z);
    }
}


y-carriage/bearing_mount: rewrite for MK52 bed

include <config.scad>
include <thing_libutils/system.scad>
include <thing_libutils/attach.scad>
include <thing_libutils/bearing-linear-data.scad>
include <thing_libutils/materials.scad>
include <thing_libutils/screws.scad>
use <thing_libutils/bearing-linear.scad>

yaxis_carriage_bearing_mount_bottom_thick = 3;
yaxis_carriage_bearing_mount_conn_bottom = [N, Z];
yaxis_carriage_bearing_mount_conn_bearing = [[0,0,yaxis_carriage_bearing_mount_bottom_thick+get(LinearBearingOuterDiameter,yaxis_bearing)/2], Z];

module yaxis_carriage_bearing_mount(part)
{
    // x distance of holes
    screw_dx=20;
    // y distance of holes
    screw_dy=0;

    carriage_plate_thread=ThreadM3;
    carriage_plate_thread_d=lookup(ThreadSize, carriage_plate_thread);

    width = screw_dx+carriage_plate_thread_d*2.5;
    bearing_OD = get(LinearBearingOuterDiameter, yaxis_bearing);
    bearing_L = get(LinearBearingLength, yaxis_bearing);
    depth = max(bearing_L+2*mm, screw_dx+carriage_plate_thread_d*2);
    height = 5+yaxis_carriage_bearing_mount_bottom_thick;

    if(part==U)
    {
        difference()
        {
            yaxis_carriage_bearing_mount(part="pos");
            yaxis_carriage_bearing_mount(part="neg");
        }
        %yaxis_carriage_bearing_mount(part="vit");
    }
    else if(part=="pos")
    {
        material(Mat_Plastic)
        rcubea([width, depth, height], align=Z);
    }
    else if(part=="neg")
    {
        for(x=[-1,1])
        for(y=[-1,1])
        tx(x*screw_dx/2)
        ty(y*screw_dy/2)
        tz(-3*mm)
        screw_cut(thread=carriage_plate_thread, head="button", head_embed=true, h=10*mm, align=Z, orient=-Z);

        /*cylindera(d=carriage_plate_thread_d, h=height+2, align=Z);*/

    }
    else if(part=="vit")
    {
    }

    translate([0,0,bearing_OD/2+yaxis_carriage_bearing_mount_bottom_thick])
    linear_bearing_mount(
        part=part,
        bearing=yaxis_bearing,
        ziptie_type=ziptie_type,
        ziptie_bearing_distance=ziptie_bearing_distance,
        orient=Y,
        mount_dir_align=Z
        );
}

module part_y_carriage_bearing_mount()
{
    c1=[N,Z];
    attach(c1,yaxis_carriage_bearing_mount_conn_bottom)
    {
        yaxis_carriage_bearing_mount();
    }
}

include <config.scad>
include <thing_libutils/system.scad>
include <thing_libutils/attach.scad>
include <thing_libutils/bearing-linear-data.scad>
include <thing_libutils/materials.scad>
use <thing_libutils/bearing-linear.scad>

yaxis_carriage_bearing_mount_bottom_thick = 3;
yaxis_carriage_bearing_mount_conn_bottom = [N, Z];
yaxis_carriage_bearing_mount_conn_bearing = [[0,0,yaxis_carriage_bearing_mount_bottom_thick+get(LinearBearingOuterDiameter,yaxis_bearing)/2], Z];

module yaxis_carriage_bearing_mount(part)
{
    // x distance of holes
    screw_dx=28;
    // y distance of holes
    screw_dy=21;

    carriage_plate_thread=ThreadM4;
    carriage_plate_thread_d=lookup(ThreadSize, carriage_plate_thread);

    width = screw_dx+carriage_plate_thread_d*2;
    bearing_OD = get(LinearBearingOuterDiameter, yaxis_bearing);
    depth = max(bearing_OD, screw_dx+carriage_plate_thread_d*2);
    height = 5+yaxis_carriage_bearing_mount_bottom_thick;

    if(part==U)
    {
        difference()
        {
            yaxis_carriage_bearing_mount(part="pos");
            yaxis_carriage_bearing_mount(part="neg");
        }
        %yaxis_carriage_bearing_mount(part="vit");
    }
    else if(part=="pos")
    {
        material(Mat_Plastic)
        rcubea ([width, depth, height], align=Z);
    }
    else if(part=="neg")
    {
        for(x=[-1,1])
        for(y=[-1,1])
        translate ([x*screw_dx/2, y*screw_dy/2, -1])
        cylindera(d=carriage_plate_thread_d, h=height+2, align=Z);

    }
    else if(part=="vit")
    {
    }

    translate([0,0,bearing_OD/2+yaxis_carriage_bearing_mount_bottom_thick])
    linear_bearing_mount(
        part=part,
        bearing=yaxis_bearing,
        ziptie_type=ziptie_type,
        ziptie_bearing_distance=ziptie_bearing_distance,
        orient=Y,
        ziptie_dist=4,
        mount_dir_align=Z
        );
}

module part_y_carriage_bearing_mount()
{
    c1=[N,Z];
    attach(c1,yaxis_carriage_bearing_mount_conn_bottom)
    {
        yaxis_carriage_bearing_mount();
    }
}


starting elements from [0,0,0] (just to make it look pretty)

eps=0.01;
wall=4;
h=wall+8+5;
$fn=60;
N=4;

module support_()
{
  translate(-wall/2*[0, 1, 0])
  {
    dist=8+wall+(8+2)/2;
    cube([dist, wall, wall]);
    translate([dist-wall, 0, 0])
      cube([wall, wall, wall+8]);
  }
}

module screw_space_()
{
  cylinder(r=(3.5+0.4)/2, h=h+eps);
  translate(-eps*[0,0,1])
    cylinder(r1=(8+0.5)/2, r2=(3.5+0.5)/2, h=4.5+eps);
}

module element()
{
  difference()
  {
    union()
    {
      cylinder(r=(8+2)/2, h=h);
      support_();
    }
    screw_space_();
  }
}

for(i=[1:N])
  translate([0, (i-1)*12, 0])
    element();

eps=0.01;
wall=4;
h=wall+8+5;
$fn=60;
N=4;

module support_()
{
  translate(-wall/2*[0, 1, 0])
  {
    dist=8+wall+(8+2)/2;
    cube([dist, wall, wall]);
    translate([dist-wall, 0, 0])
      cube([wall, wall, wall+8]);
  }
}

module screw_space_()
{
  cylinder(r=(3.5+0.4)/2, h=h+eps);
  translate(-eps*[0,0,1])
    cylinder(r1=(8+0.5)/2, r2=(3.5+0.5)/2, h=4.5+eps);
}

module element()
{
  difference()
  {
    union()
    {
      cylinder(r=(8+2)/2, h=h);
      support_();
    }
    screw_space_();
  }
}

for(i=[1:N])
  translate([0, i*12, 0])
    element();