main+config: add x carriage park option

main+config: add x carriage park option

use <thing_libutils/metric-screw.scad>
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/transforms.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/linear-extrusion.scad>;
include <thing_libutils/timing-belts.scad>;

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

/*include <extruder-direct.scad>*/
include <x-axis-end.scad>
include <x-carriage.scad>
include <y-axis-motor-mount.scad>
include <y-axis-carriage-bearing-mount.scad>
include <y-axis-carriage-belt-clamp.scad>
include <y-axis-idler.scad>
include <z-axis-motor-mount.scad>
use <gantry-upper-connector.scad>
use <gantry-lower-connector.scad>
include <psu.scad>
use <rod-clamps.scad>
use <lcd2004.scad>
use <power-panel-iec320.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>*/

// x carriage
axis_range_x_ = main_width/2 + zmotor_mount_rod_offset_x - xaxis_end_width(true) - x_carriage_w/2;
axis_range_x = [-1* axis_range_x_,-1*axis_range_x_+x_carriage_w];
axis_printrange_x = [-1/2, 1/2] * printbed_size[0];
axis_x_parked = [true, false];

axis_range_y=[0*mm,200*mm];
axis_pos_y = axis_range_y[0];
axis_range_z=[90*mm,353*mm];
axis_pos_z = axis_range_z[0];

echo(str("Build area Z: " , axis_range_z[1]-axis_range_z[0] , " mm"));

module x_axis()
{
    // x axis
    translate([0,0,axis_pos_z])
    {
        if(!preview_mode)
        {
            zrod_offset = zmotor_mount_rod_offset_x;
            for(z=[-1,1])
            for(z=xaxis_beltpath_z_offsets)
            translate([-main_width/2-zrod_offset+xaxis_end_motor_offset[0], xaxis_zaxis_distance_y, z])
            belt_path(main_width+2*(zrod_offset)+xaxis_end_motor_offset[0], 6, xaxis_pulley_inner_d, orient=[1,0,0], align=[1,0,0]);
        }

        for(x=[0:len(axis_range_x)-1])
        {
            /*#cubea(size=[x_carriage_w,10,100]);*/

            pos = axis_x_parked[x] ? axis_range_x[x] : -axis_printrange_x[x];

            translate([pos,0,0])
            mirror([x==0?0:1,0,0])
            attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],[0,0,0]])
            {
                x_carriage_withmounts(show_vitamins=true, beltpath_offset=x);

                x_carriage_extruder(show_vitamins=true, with_sensormount=x==0);
            }
        }

        // 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+.1, orient=[1,0,0]);

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

module y_axis()
{
    // y axis
    color(color_part)
    attach([[yaxis_belt_path_offset_x,main_depth/2,yaxis_motor_offset_z], [0,-1,0]], yaxis_motor_mount_conn)
    {
        yaxis_motor_mount(show_motor=true);
    }

    extrusion_idler_conn = [[yaxis_belt_path_offset_x, -main_depth/2-extrusion_size, -extrusion_size+yaxis_idler_offset_z], [0,-1,0]];
    attach(extrusion_idler_conn, yaxis_idler_conn)
    {
        color(color_part)
        yaxis_idler();

        attach(yaxis_idler_conn_pulleyblock, yaxis_idler_pulleyblock_conn)
        {
            color(color_part)
            yaxis_idler_pulleyblock(show_pulley=true);
        }
    }

    translate([yaxis_belt_path_offset_x,0,yaxis_belt_path_offset_z])
    {
        if(!preview_mode)
        {
            translate([0,main_depth/2-yaxis_motor_offset_x,0])
            {
                /*cubea([10,main_depth-yaxis_motor_offset_x,10], align=[0,-1,0]);*/
                belt_path(main_depth-yaxis_motor_offset_x-yaxis_idler_pulley_offset_y, 6, yaxis_pulley_inner_d, align=[0,-1,0], orient=[0,1,0]);
            }
        }
    }

    color(color_part)
    translate([0,-axis_pos_y,yaxis_bearing[0]/2])
    attach(yaxis_carriage_bearing_mount_conn_bearing, yaxis_belt_mount_conn)
    {
        yaxis_belt_holder();
    }

    translate([0,0,yaxis_bearing[0]/2])
    {
        for(x=[-1,1])
        for(y=[-1,1])
        {
            attach([[x*(yaxis_rod_distance/2),y*(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]);
            }
        }

        // y smooth rods
        for(x=[-1,1])
        translate([x*(yaxis_rod_distance/2), 0, 0])
        {
            color(color_rods)
            cylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=[0,1,0]);

            for(y=[-1,1])
            {
                attach([[0,y*(yaxis_bearing_distance_y/2)-axis_pos_y,0],[0,0,-1]], yaxis_carriage_bearing_mount_conn_bearing)
                {
                    yaxis_carriage_bearing_mount(show_bearing=true, show_zips=true);
                }
            }
        }

        attach(yaxis_carriage_bearing_mount_conn_bearing, [[0,axis_pos_y,0],[0,0,1]])
        {
            yaxis_carriage_size_inner = [32*mm,32*mm,0];

            // y axis plate "arms"
            for(x=[-1,1])
            for(y=[-1,1])
            hull()
            {
                translate([x*yaxis_carriage_size[0]/2, y*yaxis_carriage_size[1]/2, 0])
                {
                    cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);
                }
                translate([x*(yaxis_carriage_size[0]/2-yaxis_carriage_size_inner[0]/2), y*(yaxis_carriage_size[1]/2-yaxis_carriage_size_inner[1]/2*mm), 0])
                {
                    cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);
                }
            }

            // y axis plate
            cubea(yaxis_carriage_size - yaxis_carriage_size_inner, align=[0,0,1]);

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

}

module z_axis()
{
    // z axis
    for(x=[-1,1])
    {
        translate([x*(main_width/2),0,main_height])
        {
            mirror([x==-1?1:0,0,0])
            {
                color(color_part)
                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([x*(main_width/2), 0, 0])
        {
            translate([0,0,zaxis_motor_offset_z])
                mirror([x==-1?1:0,0,0])
                {
                    color(color_part)
                    zaxis_motor_mount(show_motor=true);

                    color(color_part)
                    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);
                    }
                }

            // z smooth rods
            translate([x*(zmotor_mount_rod_offset_x),0,0])
            {
                // z rods
                color(color_rods)
                translate([0,0,zaxis_motor_offset_z-50])
                    cylindera(h=zaxis_rod_l,d=zaxis_rod_d, align=[0,0,1]);

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

            }
        }
    }

}

module main()
{
    translate([0,0,-main_lower_dist_z/2])
    gantry_lower();

    translate(-zaxis_rod_offset)
    gantry_upper();

    x_axis();
    y_axis();
    z_axis();

    translate([-75*mm,0,0])
    translate([0,main_depth/2,0])
    translate([0,extrusion_size,0])
    translate([0,0,-main_lower_dist_z/2-extrusion_size/2])
    power_panel_iec320(orient=[0,-1,0], align=[0,1,0]);

    if(!preview_mode)
    {
        translate([0,-main_depth/2,0])
        translate([0,-extrusion_size/2,0])
        translate([0,0,-main_lower_dist_z/2])
        mount_lcd2004(show_gantry=true);

        for(x=[-1,1])
        translate([x*(main_width/2-extrusion_size),main_depth/2,-main_lower_dist_z-extrusion_size])
        {
            translate([-x*psu_a_w/2, -psu_a_d/2, psu_a_h/2])
            {
                psu_a();

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

                translate([0, psu_a_screw_dist_y/2, 0])
                    psu_a_extrusion_bracket_back();
            }
        }

        translate([0,-main_depth/2,-main_lower_dist_z-extrusion_size])
            translate([-100,100,0])
            rotate([0,0,270])
            import("stl/RAMPS1_4.STL");
    }
}

module gantry_upper()
{
    color(color_extrusion)
    for(y=[-1,1])
    translate([0,y*(main_upper_dist_y/2),0])
    {
        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        {
            if(preview_mode)
            {
                cubea(size=[extrusion_size, extrusion_size, main_height], align=[-x,0,1]);
            }
            else
            {
                linear_extrusion(h=main_height, align=[-x,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]);
            }
        }
    }

    // upper gantry connectors
    for(x=[-1,1])
    {
        translate([x*(main_width/2),0,main_height])
        {
            mirror([x==-1?1:0,0,0])
            {
                color(color_gantry_connectors)
                    gantry_upper_connector();
            }

        }
    }
}

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

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

    }

    // lower gantry connectors
    for(x=[-1,1])
    for(y=[-1,1])
    {
        translate([x*(main_width/2),y*(main_depth/2),-extrusion_size/2])
        {
            mirror([x==1?0:-1,0,0])
            mirror([0,y==1?1:0,0])
            {
                color(color_gantry_connectors)
                    gantry_lower_connector();
            }

        }
    }
}

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(x=[-1,1])
            translate([x*w/2,0,0])
                cubea([wallthick,d,h], align=[-x, 0, 0]);

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

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

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

/*psu();*/

/*%enclosure();*/

use <thing_libutils/metric-screw.scad>
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/transforms.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/linear-extrusion.scad>;
include <thing_libutils/timing-belts.scad>;

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

/*include <extruder-direct.scad>*/
include <x-axis-end.scad>
include <x-carriage.scad>
include <y-axis-motor-mount.scad>
include <y-axis-carriage-bearing-mount.scad>
include <y-axis-carriage-belt-clamp.scad>
include <y-axis-idler.scad>
include <z-axis-motor-mount.scad>
use <gantry-upper-connector.scad>
use <gantry-lower-connector.scad>
include <psu.scad>
use <rod-clamps.scad>
use <lcd2004.scad>
use <power-panel-iec320.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>*/

// x carriage
axis_range_x_ = main_width/2 + zmotor_mount_rod_offset_x - xaxis_end_width(true) - x_carriage_w/2;
axis_range_x = [-1,1] * axis_range_x_;

axis_range_y=[0*mm,200*mm];
axis_pos_y = axis_range_y[0];
axis_range_z=[90*mm,353*mm];
axis_pos_z = axis_range_z[0];

echo(str("Build area Z: " , axis_range_z[1]-axis_range_z[0] , " mm"));

module x_axis()
{
    // x axis
    translate([0,0,axis_pos_z])
    {
        if(!preview_mode)
        {
            zrod_offset = zmotor_mount_rod_offset_x;
            for(z=[-1,1])
            for(z=xaxis_beltpath_z_offsets)
            translate([-main_width/2-zrod_offset+xaxis_end_motor_offset[0], xaxis_zaxis_distance_y, z])
            belt_path(main_width+2*(zrod_offset)+xaxis_end_motor_offset[0], 6, xaxis_pulley_inner_d, orient=[1,0,0], align=[1,0,0]);
        }

        for(x=axis_range_x)
        translate([x,0,0])
        {
            /*#cubea(size=[x_carriage_w,10,100]);*/

            mirror([min(0,-x),0,0])
            attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],[0,0,0]])
            {
                x_carriage_withmounts(show_vitamins=true, beltpath_offset=x);

                x_carriage_extruder(show_vitamins=true, with_sensormount=x<=0);
            }
        }

        // 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+.1, orient=[1,0,0]);

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

module y_axis()
{
    // y axis
    color(color_part)
    attach([[yaxis_belt_path_offset_x,main_depth/2,yaxis_motor_offset_z], [0,-1,0]], yaxis_motor_mount_conn)
    {
        yaxis_motor_mount(show_motor=true);
    }

    extrusion_idler_conn = [[yaxis_belt_path_offset_x, -main_depth/2-extrusion_size, -extrusion_size+yaxis_idler_offset_z], [0,-1,0]];
    attach(extrusion_idler_conn, yaxis_idler_conn)
    {
        color(color_part)
        yaxis_idler();

        attach(yaxis_idler_conn_pulleyblock, yaxis_idler_pulleyblock_conn)
        {
            color(color_part)
            yaxis_idler_pulleyblock(show_pulley=true);
        }
    }

    translate([yaxis_belt_path_offset_x,0,yaxis_belt_path_offset_z])
    {
        if(!preview_mode)
        {
            translate([0,main_depth/2-yaxis_motor_offset_x,0])
            {
                /*cubea([10,main_depth-yaxis_motor_offset_x,10], align=[0,-1,0]);*/
                belt_path(main_depth-yaxis_motor_offset_x-yaxis_idler_pulley_offset_y, 6, yaxis_pulley_inner_d, align=[0,-1,0], orient=[0,1,0]);
            }
        }
    }

    color(color_part)
    translate([0,-axis_pos_y,yaxis_bearing[0]/2])
    attach(yaxis_carriage_bearing_mount_conn_bearing, yaxis_belt_mount_conn)
    {
        yaxis_belt_holder();
    }

    translate([0,0,yaxis_bearing[0]/2])
    {
        for(x=[-1,1])
        for(y=[-1,1])
        {
            attach([[x*(yaxis_rod_distance/2),y*(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]);
            }
        }

        // y smooth rods
        for(x=[-1,1])
        translate([x*(yaxis_rod_distance/2), 0, 0])
        {
            color(color_rods)
            cylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=[0,1,0]);

            for(y=[-1,1])
            {
                attach([[0,y*(yaxis_bearing_distance_y/2)-axis_pos_y,0],[0,0,-1]], yaxis_carriage_bearing_mount_conn_bearing)
                {
                    yaxis_carriage_bearing_mount(show_bearing=true, show_zips=true);
                }
            }
        }

        attach(yaxis_carriage_bearing_mount_conn_bearing, [[0,axis_pos_y,0],[0,0,1]])
        {
            yaxis_carriage_size_inner = [32*mm,32*mm,0];

            // y axis plate "arms"
            for(x=[-1,1])
            for(y=[-1,1])
            hull()
            {
                translate([x*yaxis_carriage_size[0]/2, y*yaxis_carriage_size[1]/2, 0])
                {
                    cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);
                }
                translate([x*(yaxis_carriage_size[0]/2-yaxis_carriage_size_inner[0]/2), y*(yaxis_carriage_size[1]/2-yaxis_carriage_size_inner[1]/2*mm), 0])
                {
                    cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);
                }
            }

            // y axis plate
            cubea(yaxis_carriage_size - yaxis_carriage_size_inner, align=[0,0,1]);

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

}

module z_axis()
{
    // z axis
    for(x=[-1,1])
    {
        translate([x*(main_width/2),0,main_height])
        {
            mirror([x==-1?1:0,0,0])
            {
                color(color_part)
                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([x*(main_width/2), 0, 0])
        {
            translate([0,0,zaxis_motor_offset_z])
                mirror([x==-1?1:0,0,0])
                {
                    color(color_part)
                    zaxis_motor_mount(show_motor=true);

                    color(color_part)
                    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);
                    }
                }

            // z smooth rods
            translate([x*(zmotor_mount_rod_offset_x),0,0])
            {
                // z rods
                color(color_rods)
                translate([0,0,zaxis_motor_offset_z-50])
                    cylindera(h=zaxis_rod_l,d=zaxis_rod_d, align=[0,0,1]);

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

            }
        }
    }

}

module main()
{
    translate([0,0,-main_lower_dist_z/2])
    gantry_lower();

    translate(-zaxis_rod_offset)
    gantry_upper();

    x_axis();
    y_axis();
    z_axis();

    translate([-75*mm,0,0])
    translate([0,main_depth/2,0])
    translate([0,extrusion_size,0])
    translate([0,0,-main_lower_dist_z/2-extrusion_size/2])
    power_panel_iec320(orient=[0,-1,0], align=[0,1,0]);

    if(!preview_mode)
    {
        translate([0,-main_depth/2,0])
        translate([0,-extrusion_size/2,0])
        translate([0,0,-main_lower_dist_z/2])
        mount_lcd2004(show_gantry=true);

        for(x=[-1,1])
        translate([x*(main_width/2-extrusion_size),main_depth/2,-main_lower_dist_z-extrusion_size])
        {
            translate([-x*psu_a_w/2, -psu_a_d/2, psu_a_h/2])
            {
                psu_a();

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

                translate([0, psu_a_screw_dist_y/2, 0])
                    psu_a_extrusion_bracket_back();
            }
        }

        translate([0,-main_depth/2,-main_lower_dist_z-extrusion_size])
            translate([-100,100,0])
            rotate([0,0,270])
            import("stl/RAMPS1_4.STL");
    }
}

module gantry_upper()
{
    color(color_extrusion)
    for(y=[-1,1])
    translate([0,y*(main_upper_dist_y/2),0])
    {
        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        {
            if(preview_mode)
            {
                cubea(size=[extrusion_size, extrusion_size, main_height], align=[-x,0,1]);
            }
            else
            {
                linear_extrusion(h=main_height, align=[-x,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]);
            }
        }
    }

    // upper gantry connectors
    for(x=[-1,1])
    {
        translate([x*(main_width/2),0,main_height])
        {
            mirror([x==-1?1:0,0,0])
            {
                color(color_gantry_connectors)
                    gantry_upper_connector();
            }

        }
    }
}

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

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

    }

    // lower gantry connectors
    for(x=[-1,1])
    for(y=[-1,1])
    {
        translate([x*(main_width/2),y*(main_depth/2),-extrusion_size/2])
        {
            mirror([x==1?0:-1,0,0])
            mirror([0,y==1?1:0,0])
            {
                color(color_gantry_connectors)
                    gantry_lower_connector();
            }

        }
    }
}

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(x=[-1,1])
            translate([x*w/2,0,0])
                cubea([wallthick,d,h], align=[-x, 0, 0]);

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

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

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

/*psu();*/

/*%enclosure();*/


fix: set the default height to 1 if none supplied to the link shape

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

/**
 * Part of the camelSCAD library.
 *
 * Rounded shapes.
 *
 * @package shape/3D
 * @author jsconan
 */

/**
 * Computes the size of a 3D rounded shape.
 *
 * @param Number|Vector [r] - The radius of the rounded part or a vector that contains radius for each dimensions.
 * @param Number|Vector [d] - The diameter of the rounded part or a vector that contains diameters for each dimensions.
 * @param Number [rx] - The length radius.
 * @param Number [ry] - The width radius.
 * @param Number [rz] - The height radius.
 * @param Number [dx] - The length diameter.
 * @param Number [dy] - The width diameter.
 * @param Number [dz] - The height diameter.
 * @returns Vector - Returns the radius vector.
 */
function sizeRounded3D(r, d, rx, ry, rz, dx, dy, dz) =
    let(
        r = apply3D(r, rx, ry, rz),
        d = apply3D(d, dx, dy, dz)
    )
    [
        d.x && !rx ? d.x / 2 : r.x,
        d.y && !ry ? d.y / 2 : r.y,
        d.z && !rz ? d.z / 2 : r.z
    ]
;

/**
 * Computes the size of an arch box.
 *
 * @param Number|Vector [size] - The size of the arch.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizeArchBox(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.y),
            divisor(s.z)
        ],
        horRadius = size.x / 2,
        radius = [
            horRadius,
            min(size.y, or(c.y, horRadius))
        ]
    )
    [ size, radius ]
;

/**
 * Computes the size of a stadium shape.
 *
 * @param Number|Vector [size] - The size of the stadium.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizeSlot(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.y * 2),
            divisor(s.z)
        ],
        horRadius = size.x / 2,
        radius = [
            horRadius,
            min(size.y / 2, or(c.y, horRadius))
        ]
    )
    [ size, radius ]
;

/**
 * Computes the size of a cushion shape.
 *
 * @param Number|Vector [size] - The size of the rounded rectangle.
 * @param Number|Vector [r] - The radius of the corners or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter of the corners  or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius of the corners.
 * @param Number [ry] - The vertical radius of the corners.
 * @param Number [dx] - The horizontal diameter of the corners.
 * @param Number [dy] - The vertical diameter of the corners.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizeCushion(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.y * 2),
            divisor(s.z)
        ],
        radius = [
            min(size.x / 2, c.x),
            min(size.y / 2, c.y)
        ]
    )
    [ size, radius.x && radius.y ? radius : [0, 0] ]
;

/**
 * Computes the size of a bullet shape.
 *
 * @param Number|Vector [size] - The size of the bullet.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizeBullet(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.x * 2),
            divisor(s.z ? s.z : c.y)
        ],
        horRadius = max(size.x, size.y) / 2,
        radius = [
            horRadius,
            min(size.z, or(c.y, horRadius))
        ]
    )
    [ size, radius ]
;

/**
 * Computes the size of a pill shape.
 *
 * @param Number|Vector [size] - The size of the pill.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizePill(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.x * 2),
            divisor(s.z ? s.z : c.y * 2)
        ],
        horRadius = max(size.x, size.y) / 2,
        radius = [
            horRadius,
            min(size.z / 2, or(c.y, horRadius))
        ]
    )
    [ size, radius ]
;

/**
 * Computes the size of a peg shape.
 *
 * @param Number|Vector [size] - The size of the peg.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizePeg(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.x * 2),
            divisor(s.z ? s.z : c.y * 2)
        ],
        radius = [
            min(max(size.x, size.y) / 2, c.x),
            min(size.z / 2, c.y)
        ]
    )
    [ size, radius.x && radius.y ? radius : [0, 0] ]
;

/**
 * Computes the size of a plate shape.
 *
 * @param Number|Vector [size] - The size of the plate.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizePlate(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.x * 2),
            divisor(s.z ? s.z : c.y * 2)
        ],
        verRadius = size.z / 2,
        radius = [
            min(max(size.x, size.y) / 2, or(c.x, verRadius)),
            verRadius
        ]
    )
    [ size, radius ]
;

/**
 * Computes the points that draw the sketch of a bullet shape.
 *
 * @param Number|Vector [size] - The size of the bullet.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[]
 */
function drawBullet(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        specs = sizeBullet(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy),
        size = specs[0],
        radius = specs[1],
        center = [
            0, size.z - radius.y
        ],
        points = arc(r=radius, o=center, a=RIGHT)
    )
    complete(points, [radius.x, 0], [0, 0])
;

/**
 * Computes the points that draw the sketch of a pill shape.
 *
 * @param Number|Vector [size] - The size of the pill.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[]
 */
function drawPill(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        specs = sizePill(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy),
        size = specs[0],
        radius = specs[1],
        center = [
            0, size.z / 2 - radius.y
        ]
    )
    center == [0, 0] ? arc(r=radius, a1=-RIGHT, a2=RIGHT)
   :concat(
        arc(r=radius, o=-center, a=RIGHT, a1=-RIGHT),
        arc(r=radius, o=center, a=RIGHT)
    )
;

/**
 * Computes the points that draw the sketch of a peg shape.
 *
 * @param Number|Vector [size] - The size of the peg.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[]
 */
function drawPeg(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        specs = sizePeg(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy),
        size = specs[0],
        radius = specs[1],
        right = max(size.x, size.y) / 2,
        top = size.z / 2,
        center = [
            right - radius.x,
            top - radius.y
        ]
    )
    radius == [0, 0] ? [ [right, top], [0, top], [0, -top], [right, -top] ]
   :center == [0, 0] ? arc(r=radius, a1=-RIGHT, a2=RIGHT)
   :complete(
        concat(
            arc(r=radius, o=[center.x, -center.y], a1=QUADRANT_3, a2=QUADRANT_4),
            arc(r=radius, o=center, a1=0, a2=QUADRANT_1)
        ),
        [0, -top],
        [0, top]
    )
;

/**
 * Computes the points that draw the sketch of a plate shape.
 *
 * @param Number|Vector [size] - The size of the plate.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[]
 */
function drawPlate(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        specs = sizePlate(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy),
        size = specs[0],
        radius = specs[1],
        center = [
            max(size.x, size.y) / 2 - radius.x, 0
        ],
        points = arc(r=radius, o=center, a1=-RIGHT, a2=RIGHT)
    )
    center == [0, 0] ? points
   :complete(points, -[0, radius.y], [0, radius.y])
;

/**
 * Creates an arch box at the origin.
 *
 * @param Number|Vector [size] - The size of the arch.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @param Boolean [center] - Whether or not center the box on the vertical axis.
 */
module archBox(size, r, d, l, w, h, rx, ry, dx, dy, center) {
    size = sizeArchBox(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    linear_extrude(height=size[0].z, center=center, convexity=10) {
        arch(size[0], size[1]);
    }
}

/**
 * Creates a slot shape at the origin.
 *
 * @param Number|Vector [size] - The size of the stadium.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @param Boolean [center] - Whether or not center the box on the vertical axis.
 */
module slot(size, r, d, l, w, h, rx, ry, dx, dy, center) {
    size = sizeSlot(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    linear_extrude(height=size[0].z, center=center, convexity=10) {
        stadium(size[0], size[1]);
    }
}

/**
 * Creates a cushion shape at the origin.
 *
 * @param Number|Vector [size] - The size of the rounded rectangle.
 * @param Number|Vector [r] - The radius of the corners or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter of the corners  or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius of the corners.
 * @param Number [ry] - The vertical radius of the corners.
 * @param Number [dx] - The horizontal diameter of the corners.
 * @param Number [dy] - The vertical diameter of the corners.
 * @param Boolean [center] - Whether or not center the box on the vertical axis.
 */
module cushion(size, r, d, l, w, h, rx, ry, dx, dy, center) {
    size = sizeCushion(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    linear_extrude(height=size[0].z, center=center, convexity=10) {
        roundedRectangle(size[0], size[1]);
    }
}

/**
 * Creates a bullet shape at the origin.
 *
 * @param Number|Vector [size] - The size of the bullet.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 */
module bullet(size, r, d, l, w, h, rx, ry, dx, dy) {
    specs = sizeBullet(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    resize(specs[0]) {
        rotate_extrude(convexity=10) {
            polygon(
                points=drawBullet(size=specs[0], r=specs[1]),
                convexity=10
            );
        }
    }
}

/**
 * Creates a pill shape at the origin.
 *
 * @param Number|Vector [size] - The size of the pill.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 */
module pill(size, r, d, l, w, h, rx, ry, dx, dy) {
    specs = sizePill(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    resize(specs[0]) {
        rotate_extrude(convexity=10) {
            polygon(
                points=drawPill(size=specs[0], r=specs[1]),
                convexity=10
            );
        }
    }
}

/**
 * Creates a peg shape at the origin.
 *
 * @param Number|Vector [size] - The size of the peg.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 */
module peg(size, r, d, l, w, h, rx, ry, dx, dy) {
    specs = sizePeg(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    resize(specs[0]) {
        rotate_extrude(convexity=10) {
            polygon(
                points=drawPeg(size=specs[0], r=specs[1]),
                convexity=10
            );
        }
    }
}

/**
 * Creates a plate shape at the origin.
 *
 * @param Number|Vector [size] - The size of the plate.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 */
module plate(size, r, d, l, w, h, rx, ry, dx, dy) {
    specs = sizePlate(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    resize(specs[0]) {
        rotate_extrude(convexity=10) {
            polygon(
                points=drawPlate(size=specs[0], r=specs[1]),
                convexity=10
            );
        }
    }
}

/**
 * Creates a rounded corner wedge at the origin.
 * For now the function can only handle square corner.
 *
 * @param Number [size] - The size of the corner.
 * @param Number [r] - The radius of the round.
 * @param Number [h] - The height of the solid.
 * @param Number [d] - The diameter of the round.
 * @param String|Vector [p] - The position of the corner, as a cardinal point (default: "ne", aka North East).
 * @param Boolean [convex] - Whether makes a convex corner (default: false).
 * @param Number [adjust] - An adjust value added to the size in order to fix wall alignment issue.
 * @param Boolean [center] - Whether or not center the solid on the vertical axis.
 */
module roundedCornerWedge(size, r, h, d, p, convex, adjust, center) {
    linear_extrude(height=divisor(h), center=center, convexity=10) {
        roundedCorner(size=size, r=r, d=d, p=p, convex=convex, adjust=adjust);
    }
}

/**
 * Draws a link.
 * @param Vector|Number neck - The size of the link neck.
 * @param Vector|Number bulk - The size of the link bulb.
 * @param Number Height - The thickness of the link.
 * @param Number [w] - The width of the neck.
 * @param Number [h] - The height of the neck.
 * @param Number [rx] - The horizontal radius of the bulb.
 * @param Number [ry] - The vertical radius of the bulb.
 * @param Number [dx] - The horizontal diameter of the bulb.
 * @param Number [dy] - The vertical diameter of the bulb.
 * @param Number [distance] - An additional distance added to the outline of the profile.
 * @param Boolean [center] - Whether or not center the solid on the vertical axis.
 */
module link(neck, bulb, height, w, h, rx, ry, dx, dy, distance = 0, center=false) {
    linear_extrude(height=divisor(height), center=center, convexity=10) {
        linkProfile(
            neck = neck,
            bulb = bulb,
            w = w,
            h = h,
            rx = rx,
            ry = ry,
            dx = dx,
            dy = dy,
            distance = distance
        );
    }
}

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

/**
 * Part of the camelSCAD library.
 *
 * Rounded shapes.
 *
 * @package shape/3D
 * @author jsconan
 */

/**
 * Computes the size of a 3D rounded shape.
 *
 * @param Number|Vector [r] - The radius of the rounded part or a vector that contains radius for each dimensions.
 * @param Number|Vector [d] - The diameter of the rounded part or a vector that contains diameters for each dimensions.
 * @param Number [rx] - The length radius.
 * @param Number [ry] - The width radius.
 * @param Number [rz] - The height radius.
 * @param Number [dx] - The length diameter.
 * @param Number [dy] - The width diameter.
 * @param Number [dz] - The height diameter.
 * @returns Vector - Returns the radius vector.
 */
function sizeRounded3D(r, d, rx, ry, rz, dx, dy, dz) =
    let(
        r = apply3D(r, rx, ry, rz),
        d = apply3D(d, dx, dy, dz)
    )
    [
        d.x && !rx ? d.x / 2 : r.x,
        d.y && !ry ? d.y / 2 : r.y,
        d.z && !rz ? d.z / 2 : r.z
    ]
;

/**
 * Computes the size of an arch box.
 *
 * @param Number|Vector [size] - The size of the arch.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizeArchBox(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.y),
            divisor(s.z)
        ],
        horRadius = size.x / 2,
        radius = [
            horRadius,
            min(size.y, or(c.y, horRadius))
        ]
    )
    [ size, radius ]
;

/**
 * Computes the size of a stadium shape.
 *
 * @param Number|Vector [size] - The size of the stadium.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizeSlot(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.y * 2),
            divisor(s.z)
        ],
        horRadius = size.x / 2,
        radius = [
            horRadius,
            min(size.y / 2, or(c.y, horRadius))
        ]
    )
    [ size, radius ]
;

/**
 * Computes the size of a cushion shape.
 *
 * @param Number|Vector [size] - The size of the rounded rectangle.
 * @param Number|Vector [r] - The radius of the corners or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter of the corners  or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius of the corners.
 * @param Number [ry] - The vertical radius of the corners.
 * @param Number [dx] - The horizontal diameter of the corners.
 * @param Number [dy] - The vertical diameter of the corners.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizeCushion(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.y * 2),
            divisor(s.z)
        ],
        radius = [
            min(size.x / 2, c.x),
            min(size.y / 2, c.y)
        ]
    )
    [ size, radius.x && radius.y ? radius : [0, 0] ]
;

/**
 * Computes the size of a bullet shape.
 *
 * @param Number|Vector [size] - The size of the bullet.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizeBullet(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.x * 2),
            divisor(s.z ? s.z : c.y)
        ],
        horRadius = max(size.x, size.y) / 2,
        radius = [
            horRadius,
            min(size.z, or(c.y, horRadius))
        ]
    )
    [ size, radius ]
;

/**
 * Computes the size of a pill shape.
 *
 * @param Number|Vector [size] - The size of the pill.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizePill(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.x * 2),
            divisor(s.z ? s.z : c.y * 2)
        ],
        horRadius = max(size.x, size.y) / 2,
        radius = [
            horRadius,
            min(size.z / 2, or(c.y, horRadius))
        ]
    )
    [ size, radius ]
;

/**
 * Computes the size of a peg shape.
 *
 * @param Number|Vector [size] - The size of the peg.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizePeg(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.x * 2),
            divisor(s.z ? s.z : c.y * 2)
        ],
        radius = [
            min(max(size.x, size.y) / 2, c.x),
            min(size.z / 2, c.y)
        ]
    )
    [ size, radius.x && radius.y ? radius : [0, 0] ]
;

/**
 * Computes the size of a plate shape.
 *
 * @param Number|Vector [size] - The size of the plate.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[] - Returns an array containing the size vector and the radius vector.
 */
function sizePlate(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        s = apply3D(size, l, w, h),
        c = sizeRounded2D(r=r, d=d, rx=rx, ry=ry, dx=dx, dy=dy),
        size = [
            divisor(s.x ? s.x : c.x * 2),
            divisor(s.y ? s.y : c.x * 2),
            divisor(s.z ? s.z : c.y * 2)
        ],
        verRadius = size.z / 2,
        radius = [
            min(max(size.x, size.y) / 2, or(c.x, verRadius)),
            verRadius
        ]
    )
    [ size, radius ]
;

/**
 * Computes the points that draw the sketch of a bullet shape.
 *
 * @param Number|Vector [size] - The size of the bullet.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[]
 */
function drawBullet(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        specs = sizeBullet(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy),
        size = specs[0],
        radius = specs[1],
        center = [
            0, size.z - radius.y
        ],
        points = arc(r=radius, o=center, a=RIGHT)
    )
    complete(points, [radius.x, 0], [0, 0])
;

/**
 * Computes the points that draw the sketch of a pill shape.
 *
 * @param Number|Vector [size] - The size of the pill.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[]
 */
function drawPill(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        specs = sizePill(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy),
        size = specs[0],
        radius = specs[1],
        center = [
            0, size.z / 2 - radius.y
        ]
    )
    center == [0, 0] ? arc(r=radius, a1=-RIGHT, a2=RIGHT)
   :concat(
        arc(r=radius, o=-center, a=RIGHT, a1=-RIGHT),
        arc(r=radius, o=center, a=RIGHT)
    )
;

/**
 * Computes the points that draw the sketch of a peg shape.
 *
 * @param Number|Vector [size] - The size of the peg.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[]
 */
function drawPeg(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        specs = sizePeg(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy),
        size = specs[0],
        radius = specs[1],
        right = max(size.x, size.y) / 2,
        top = size.z / 2,
        center = [
            right - radius.x,
            top - radius.y
        ]
    )
    radius == [0, 0] ? [ [right, top], [0, top], [0, -top], [right, -top] ]
   :center == [0, 0] ? arc(r=radius, a1=-RIGHT, a2=RIGHT)
   :complete(
        concat(
            arc(r=radius, o=[center.x, -center.y], a1=QUADRANT_3, a2=QUADRANT_4),
            arc(r=radius, o=center, a1=0, a2=QUADRANT_1)
        ),
        [0, -top],
        [0, top]
    )
;

/**
 * Computes the points that draw the sketch of a plate shape.
 *
 * @param Number|Vector [size] - The size of the plate.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @returns Vector[]
 */
function drawPlate(size, r, d, l, w, h, rx, ry, dx, dy) =
    let(
        specs = sizePlate(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy),
        size = specs[0],
        radius = specs[1],
        center = [
            max(size.x, size.y) / 2 - radius.x, 0
        ],
        points = arc(r=radius, o=center, a1=-RIGHT, a2=RIGHT)
    )
    center == [0, 0] ? points
   :complete(points, -[0, radius.y], [0, radius.y])
;

/**
 * Creates an arch box at the origin.
 *
 * @param Number|Vector [size] - The size of the arch.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @param Boolean [center] - Whether or not center the box on the vertical axis.
 */
module archBox(size, r, d, l, w, h, rx, ry, dx, dy, center) {
    size = sizeArchBox(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    linear_extrude(height=size[0].z, center=center, convexity=10) {
        arch(size[0], size[1]);
    }
}

/**
 * Creates a slot shape at the origin.
 *
 * @param Number|Vector [size] - The size of the stadium.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 * @param Boolean [center] - Whether or not center the box on the vertical axis.
 */
module slot(size, r, d, l, w, h, rx, ry, dx, dy, center) {
    size = sizeSlot(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    linear_extrude(height=size[0].z, center=center, convexity=10) {
        stadium(size[0], size[1]);
    }
}

/**
 * Creates a cushion shape at the origin.
 *
 * @param Number|Vector [size] - The size of the rounded rectangle.
 * @param Number|Vector [r] - The radius of the corners or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter of the corners  or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius of the corners.
 * @param Number [ry] - The vertical radius of the corners.
 * @param Number [dx] - The horizontal diameter of the corners.
 * @param Number [dy] - The vertical diameter of the corners.
 * @param Boolean [center] - Whether or not center the box on the vertical axis.
 */
module cushion(size, r, d, l, w, h, rx, ry, dx, dy, center) {
    size = sizeCushion(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    linear_extrude(height=size[0].z, center=center, convexity=10) {
        roundedRectangle(size[0], size[1]);
    }
}

/**
 * Creates a bullet shape at the origin.
 *
 * @param Number|Vector [size] - The size of the bullet.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 */
module bullet(size, r, d, l, w, h, rx, ry, dx, dy) {
    specs = sizeBullet(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    resize(specs[0]) {
        rotate_extrude(convexity=10) {
            polygon(
                points=drawBullet(size=specs[0], r=specs[1]),
                convexity=10
            );
        }
    }
}

/**
 * Creates a pill shape at the origin.
 *
 * @param Number|Vector [size] - The size of the pill.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 */
module pill(size, r, d, l, w, h, rx, ry, dx, dy) {
    specs = sizePill(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    resize(specs[0]) {
        rotate_extrude(convexity=10) {
            polygon(
                points=drawPill(size=specs[0], r=specs[1]),
                convexity=10
            );
        }
    }
}

/**
 * Creates a peg shape at the origin.
 *
 * @param Number|Vector [size] - The size of the peg.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 */
module peg(size, r, d, l, w, h, rx, ry, dx, dy) {
    specs = sizePeg(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    resize(specs[0]) {
        rotate_extrude(convexity=10) {
            polygon(
                points=drawPeg(size=specs[0], r=specs[1]),
                convexity=10
            );
        }
    }
}

/**
 * Creates a plate shape at the origin.
 *
 * @param Number|Vector [size] - The size of the plate.
 * @param Number|Vector [r] - The radius or a vector that contains horizontal and vertical radius.
 * @param Number|Vector [d] - The diameter or a vector that contains horizontal and vertical diameters.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [h] - The overall height.
 * @param Number [rx] - The horizontal radius.
 * @param Number [ry] - The vertical radius.
 * @param Number [dx] - The horizontal diameter.
 * @param Number [dy] - The vertical diameter.
 */
module plate(size, r, d, l, w, h, rx, ry, dx, dy) {
    specs = sizePlate(size=size, r=r, d=d, l=l, w=w, h=h, rx=rx, ry=ry, dx=dx, dy=dy);
    resize(specs[0]) {
        rotate_extrude(convexity=10) {
            polygon(
                points=drawPlate(size=specs[0], r=specs[1]),
                convexity=10
            );
        }
    }
}

/**
 * Creates a rounded corner wedge at the origin.
 * For now the function can only handle square corner.
 *
 * @param Number [size] - The size of the corner.
 * @param Number [r] - The radius of the round.
 * @param Number [h] - The height of the solid.
 * @param Number [d] - The diameter of the round.
 * @param String|Vector [p] - The position of the corner, as a cardinal point (default: "ne", aka North East).
 * @param Boolean [convex] - Whether makes a convex corner (default: false).
 * @param Number [adjust] - An adjust value added to the size in order to fix wall alignment issue.
 * @param Boolean [center] - Whether or not center the solid on the vertical axis.
 */
module roundedCornerWedge(size, r, h, d, p, convex, adjust, center) {
    linear_extrude(height=divisor(h), center=center, convexity=10) {
        roundedCorner(size=size, r=r, d=d, p=p, convex=convex, adjust=adjust);
    }
}

/**
 * Draws a link.
 * @param Vector|Number neck - The size of the link neck.
 * @param Vector|Number bulk - The size of the link bulb.
 * @param Number Height - The thickness of the link.
 * @param Number [w] - The width of the neck.
 * @param Number [h] - The height of the neck.
 * @param Number [rx] - The horizontal radius of the bulb.
 * @param Number [ry] - The vertical radius of the bulb.
 * @param Number [dx] - The horizontal diameter of the bulb.
 * @param Number [dy] - The vertical diameter of the bulb.
 * @param Number [distance] - An additional distance added to the outline of the profile.
 * @param Boolean [center] - Whether or not center the solid on the vertical axis.
 */
module link(neck, bulb, height, w, h, rx, ry, dx, dy, distance = 0, center=false) {
    linear_extrude(height=height, center=center, convexity=10) {
        linkProfile(
            neck = neck,
            bulb = bulb,
            w = w,
            h = h,
            rx = rx,
            ry = ry,
            dx = dx,
            dy = dy,
            distance = distance
        );
    }
}


adding comments

adding comments

/*

LogoBot.scad

*/

// Master include statement, causes everything else for the model to be included
include <config/config.scad>

// Master assembly
//   Defined within: assemblies/LogoBot.scad
LogoBotAssembly();

/*

LogoBot.scad

*/

// Master include statement, causes everything else for the model to be included
include <config/config.scad>

// Master assembly
LogoBotAssembly();


model of the tube top

model of the tube top

size = [92.75, 41, 15];
wall = 1.75;
spacing = 2;
l = 3.2;

module tooth()
{
  difference()
  {
    cube([l, wall, 16]);
    translate([0, 0, 16+l/2.5])
      rotate([0, 45, 0])
        translate([0, 0, -l])
          cube(l*[1, 1, 2]);
  }
}

// body
difference()
{
  cube(size);
  translate(wall*[1, 0, 1])
    cube(size - wall*[2, 1, 1]);
}

// side teeth
for(dy=[5, 25])
  translate([wall+spacing, dy, wall])
  {
    tooth();
    translate([size[0]-2*(wall+spacing), wall, 0])
      rotate([0, 0, 180])
        tooth();
  }

// upper teeth
for(dx=[0:3])
  translate([wall + 15 + dx*18.5, size[1]-wall-spacing-l, 0])
    translate([0, l, 0])
      rotate([0, 0, -90])
        tooth();


added both horizontal and vertical rod at the same time

error: pathspec '3d_cube/cube_rod.scad' did not match any file(s) known to git


timing-belts: add belt_path

timing-belts: add belt_path

/*Parametric belting section generator
 * types GT2 2mm T2.5 T5 T10 MXL
 *
 * (c) ALJ_rprp
 *
 * Derived from http://www.thingiverse.com/
 * thing:19758 By The DoomMeister
 * thing:16627 by Droftarts
 *
 * licence GPL 2.1 or later
 *
 * deal properly with ends
 * allow circular segments
 * length is given in mm not nb of teeth
 * belt is centered at z=0 and extend along x
 *
 * TODO : add ofset for cosmetic teeth liaisons between segments
 *
 * usage :
 * belt_angle(prf = tT2_5, rad=25, bwdth = 6, angle=90)
 * belt_len  (prf = tT2_5, belt_width = 6, len = 10)
 */

include <shapes.scad>
include <transforms.scad>

// profiles
tGT2_2=0;
tT2_5=1;
tT5=2;
tT10=3;
tMXL=4;

/*test_belt();*/

module test_belt()
{
    $fs= 0.5;
    $fa = 4;

    translate([-00.5,0,5.5]) cube([1,40,1]);

    stack(dist=20, axis=[0,0,-1])
    {
        belt_len(profile = tT10, belt_width = 10, len = 100);
        color("red") belt_len(profile = tT5, belt_width = 10, len = 100);
        color("green") belt_len(profile = tT2_5, belt_width = 10, len = 80);
        color("blue") belt_len(profile = tGT2_2, belt_width = 10, len = 100);
        color("orange") belt_len(profile = tMXL, belt_width = 10, len = 100);

        belt_angle(tT10,20,10,180);
        belt_angle(tT5,15,10,90);
        belt_angle(tT2_5,25,10,120);
        belt_angle(tGT2_2,30,10,40);
        belt_angle(tMXL,30,10,40);

        color("aquamarine") {
            belt_len(tT2_5,10, 50);
            translate([50,30,0]) rotate([0,0,180]) belt_len(tT2_5,10,50);
            translate([ 0,30,0]) rotate([0,0,180]) belt_angle(tT2_5,15,10,180);
            translate([50,0,0]) rotate([0,0,0]) belt_angle(tT2_5,15,10,180);
        }
    }
}

module belt_path(len=200*mm, belt_width=6*mm, pulley_d=10*mm, belt=tGT2_2, align=[0,0,0], orient=[0,0,1])
{
    size_align(size=[pulley_d, belt_width, len], align=align, orient=orient)
    orient([1,0,0])
    orient([0,1,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 belt_angle(prf = tT2_5, rad=25, bwdth = 6, angle=90)
{
    av=360/2/rad/3.14159*tpitch[prf];
    bk=bk_thick[prf];

    nn=ceil(angle/av);
    ang=av*nn;

    intersection()
    {
        translate([0,-bk-.5,0])
        pie_slice(r=rad+bk+.5,start_angle=-90,end_angle=angle-90,h=bwdth, align=[0,1,0]);

        union ()
        {
            for(i=[0:nn])
            {
                translate ([0,rad,-bwdth/2])
                rotate ([0,0,av*i])
                translate ([0,-rad,0])
                draw_tooth(prf,0,bwdth);
            }

            translate ([0,rad,-bwdth/2])
            rotate([0,0,-90])
            rotate_extrude(angle = angle)
                polygon([[rad,0],[rad+bk,0],[rad+bk,bwdth],[rad,bwdth]]);
        }
    }
}

//Outer Module
module belt_len(profile = tT2_5, belt_width = 6, len = 10){
    if ( profile == tT2_5 ) { _belt_len(prf=profile,len = len,bwdth = belt_width);}
    if ( profile == tT5 )   { _belt_len(prf=profile,len = len,bwdth = belt_width);}
    if ( profile == tT10 )  { _belt_len(prf=profile,len = len,bwdth = belt_width);}
    if ( profile == tMXL )	{ _belt_len(prf=profile,len = len,bwdth = belt_width);}
    if ( profile == tGT2_2 ){ _belt_len(prf=profile,len = len,bwdth = belt_width);}
}

//inner module
module _belt_len(prf = -1, len = 10, bwdth = 5) {

    n=ceil(len/tpitch[prf]);

    translate ([0,0,-bwdth/2]) intersection() {
        union(){
            for( i = [0:n]) {
                draw_tooth(prf,i,bwdth);
            }
            translate([-1,-bk_thick[prf],0])cube([len+1,bk_thick[prf],bwdth]);
        }
        translate([0,-bk_thick[prf],0])cube([len,max_h[prf]+bk_thick[prf],bwdth]);
    }
}

module draw_tooth(prf,i,bwdth) {
    if ( prf == tT2_5 ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_T2_5);}
    if ( prf == tT5 ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_T5);}
    if ( prf == tT10 ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_T10);}
    if ( prf == tMXL ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_MXL);}
    if ( prf == tGT2_2 ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_GT2_2);}
}

/************************************
 *				DATA TABLES					*
 ************************************/
    tpitch = [2,2.5,5,10,2.032];
    bk_thick=[0.6,0.6,1,2,0.64];
    max_h=[0.76447, 0.699911, 1.189895, 2.499784, 0.508035];

    pf_GT2_2=  [[ 0.747183,-0.5     ],[ 0.747183, 0       ],[ 0.647876, 0.037218],
    [ 0.598311, 0.130528],[ 0.578556, 0.238423],[ 0.547158, 0.343077],
    [ 0.504649, 0.443762],[ 0.451556, 0.53975 ],[ 0.358229, 0.636924],
    [ 0.2484  , 0.707276],[ 0.127259, 0.750044],[ 0       , 0.76447 ],
    [-0.127259, 0.750044],[-0.2484  , 0.707276],[-0.358229, 0.636924],
    [-0.451556, 0.53975 ],[-0.504797, 0.443762],[-0.547291, 0.343077],
    [-0.578605, 0.238423],[-0.598311, 0.130528],[-0.648009, 0.037218],
    [-0.747183, 0       ],[-0.747183,-0.5]];
pf_T2_5=   [[-0.839258,-0.5     ],[-0.839258, 0       ],[-0.770246, 0.021652],
    [-0.726369, 0.079022],[-0.529167, 0.620889],[-0.485025, 0.67826 ],
    [-0.416278, 0.699911],[ 0.416278, 0.699911],[ 0.484849, 0.67826 ],
    [ 0.528814, 0.620889],[ 0.726369, 0.079022],[ 0.770114, 0.021652],
    [ 0.839258, 0       ],[ 0.839258,-0.5]];
pf_T5= 	  [[-1.632126,-0.5     ],[-1.632126, 0       ],[-1.568549, 0.004939],
    [-1.507539, 0.019367],[-1.450023, 0.042686],[-1.396912, 0.074224],
    [-1.349125, 0.113379],[-1.307581, 0.159508],[-1.273186, 0.211991],
    [-1.246868, 0.270192],[-1.009802, 0.920362],[-0.983414, 0.978433],
    [-0.949018, 1.030788],[-0.907524, 1.076798],[-0.859829, 1.115847],
    [-0.80682 , 1.147314],[-0.749402, 1.170562],[-0.688471, 1.184956],
    [-0.624921, 1.189895],[ 0.624971, 1.189895],[ 0.688622, 1.184956],
    [ 0.749607, 1.170562],[ 0.807043, 1.147314],[ 0.860055, 1.115847],
    [ 0.907754, 1.076798],[ 0.949269, 1.030788],[ 0.9837  , 0.978433],
    [ 1.010193, 0.920362],[ 1.246907, 0.270192],[ 1.273295, 0.211991],
    [ 1.307726, 0.159508],[ 1.349276, 0.113379],[ 1.397039, 0.074224],
    [ 1.450111, 0.042686],[ 1.507589, 0.019367],[ 1.568563, 0.004939],
    [ 1.632126, 0       ],[ 1.632126,-0.5]];
pf_T10=    [[-3.06511 ,-1       ],[-3.06511 , 0       ],[-2.971998, 0.007239],
    [-2.882718, 0.028344],[-2.79859 , 0.062396],[-2.720931, 0.108479],
    [-2.651061, 0.165675],[-2.590298, 0.233065],[-2.539962, 0.309732],
    [-2.501371, 0.394759],[-1.879071, 2.105025],[-1.840363, 2.190052],
    [-1.789939, 2.266719],[-1.729114, 2.334109],[-1.659202, 2.391304],
    [-1.581518, 2.437387],[-1.497376, 2.47144 ],[-1.408092, 2.492545],
    [-1.314979, 2.499784],[ 1.314979, 2.499784],[ 1.408091, 2.492545],
    [ 1.497371, 2.47144 ],[ 1.581499, 2.437387],[ 1.659158, 2.391304],
    [ 1.729028, 2.334109],[ 1.789791, 2.266719],[ 1.840127, 2.190052],
    [ 1.878718, 2.105025],[ 2.501018, 0.394759],[ 2.539726, 0.309732],
    [ 2.59015 , 0.233065],[ 2.650975, 0.165675],[ 2.720887, 0.108479],
    [ 2.798571, 0.062396],[ 2.882713, 0.028344],[ 2.971997, 0.007239],
    [ 3.06511 , 0       ],[ 3.06511 ,-1]];
pf_MXL=    [[-0.660421,-0.5     ],[-0.660421, 0       ],[-0.621898, 0.006033],
    [-0.587714, 0.023037],[-0.560056, 0.049424],[-0.541182, 0.083609],
    [-0.417357, 0.424392],[-0.398413, 0.458752],[-0.370649, 0.48514 ],
    [-0.336324, 0.502074],[-0.297744, 0.508035],[ 0.297744, 0.508035],
    [ 0.336268, 0.502074],[ 0.370452, 0.48514 ],[ 0.39811 , 0.458752],
    [ 0.416983, 0.424392],[ 0.540808, 0.083609],[ 0.559752, 0.049424],
    [ 0.587516, 0.023037],[ 0.621841, 0.006033],[ 0.660421, 0       ],
    [ 0.660421,-0.5]];

/*Parametric belting section generator
 * types GT2 2mm T2.5 T5 T10 MXL
 *
 * (c) ALJ_rprp
 *
 * Derived from http://www.thingiverse.com/
 * thing:19758 By The DoomMeister
 * thing:16627 by Droftarts
 *
 * licence GPL 2.1 or later
 *
 * deal properly with ends
 * allow circular segments
 * length is given in mm not nb of teeth
 * belt is centered at z=0 and extend along x
 *
 * TODO : add ofset for cosmetic teeth liaisons between segments
 *
 * usage :
 * belt_angle(prf = tT2_5, rad=25, bwdth = 6, angle=90)
 * belt_len  (prf = tT2_5, belt_width = 6, len = 10)
 */

include <shapes.scad>
include <transforms.scad>

// profiles
tGT2_2=0;
tT2_5=1;
tT5=2;
tT10=3;
tMXL=4;

/*test_belt();*/

module test_belt()
{
    $fs= 0.5;
    $fa = 4;

    translate([-00.5,0,5.5]) cube([1,40,1]);

    stack(dist=20, axis=[0,0,-1])
    {
        belt_len(profile = tT10, belt_width = 10, len = 100);
        color("red") belt_len(profile = tT5, belt_width = 10, len = 100);
        color("green") belt_len(profile = tT2_5, belt_width = 10, len = 80);
        color("blue") belt_len(profile = tGT2_2, belt_width = 10, len = 100);
        color("orange") belt_len(profile = tMXL, belt_width = 10, len = 100);

        belt_angle(tT10,20,10,180);
        belt_angle(tT5,15,10,90);
        belt_angle(tT2_5,25,10,120);
        belt_angle(tGT2_2,30,10,40);
        belt_angle(tMXL,30,10,40);

        color("aquamarine") {
            belt_len(tT2_5,10, 50);
            translate([50,30,0]) rotate([0,0,180]) belt_len(tT2_5,10,50);
            translate([ 0,30,0]) rotate([0,0,180]) belt_angle(tT2_5,15,10,180);
            translate([50,0,0]) rotate([0,0,0]) belt_angle(tT2_5,15,10,180);
        }
    }
}

module belt_angle(prf = tT2_5, rad=25, bwdth = 6, angle=90)
{
    av=360/2/rad/3.14159*tpitch[prf];
    bk=bk_thick[prf];

    nn=ceil(angle/av);
    ang=av*nn;

    intersection()
    {
        translate([0,-bk-.5,0])
        pie_slice(r=rad+bk+.5,start_angle=-90,end_angle=angle-90,h=bwdth, align=[0,1,0]);

        union ()
        {
            for(i=[0:nn])
            {
                translate ([0,rad,-bwdth/2])
                rotate ([0,0,av*i])
                translate ([0,-rad,0])
                draw_tooth(prf,0,bwdth);
            }

            translate ([0,rad,-bwdth/2])
            rotate([0,0,-90])
            rotate_extrude(angle = angle)
                polygon([[rad,0],[rad+bk,0],[rad+bk,bwdth],[rad,bwdth]]);
        }
    }
}

//Outer Module
module belt_len(profile = tT2_5, belt_width = 6, len = 10){
    if ( profile == tT2_5 ) { _belt_len(prf=profile,len = len,bwdth = belt_width);}
    if ( profile == tT5 )   { _belt_len(prf=profile,len = len,bwdth = belt_width);}
    if ( profile == tT10 )  { _belt_len(prf=profile,len = len,bwdth = belt_width);}
    if ( profile == tMXL )	{ _belt_len(prf=profile,len = len,bwdth = belt_width);}
    if ( profile == tGT2_2 ){ _belt_len(prf=profile,len = len,bwdth = belt_width);}
}

//inner module
module _belt_len(prf = -1, len = 10, bwdth = 5) {

    n=ceil(len/tpitch[prf]);

    translate ([0,0,-bwdth/2]) intersection() {
        union(){
            for( i = [0:n]) {
                draw_tooth(prf,i,bwdth);
            }
            translate([-1,-bk_thick[prf],0])cube([len+1,bk_thick[prf],bwdth]);
        }
        translate([0,-bk_thick[prf],0])cube([len,max_h[prf]+bk_thick[prf],bwdth]);
    }
}

module draw_tooth(prf,i,bwdth) {
    if ( prf == tT2_5 ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_T2_5);}
    if ( prf == tT5 ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_T5);}
    if ( prf == tT10 ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_T10);}
    if ( prf == tMXL ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_MXL);}
    if ( prf == tGT2_2 ) { translate([tpitch[prf]*i,0,0])
        linear_extrude(height=bwdth) polygon(pf_GT2_2);}
}

/************************************
 *				DATA TABLES					*
 ************************************/
    tpitch = [2,2.5,5,10,2.032];
    bk_thick=[0.6,0.6,1,2,0.64];
    max_h=[0.76447, 0.699911, 1.189895, 2.499784, 0.508035];

    pf_GT2_2=  [[ 0.747183,-0.5     ],[ 0.747183, 0       ],[ 0.647876, 0.037218],
    [ 0.598311, 0.130528],[ 0.578556, 0.238423],[ 0.547158, 0.343077],
    [ 0.504649, 0.443762],[ 0.451556, 0.53975 ],[ 0.358229, 0.636924],
    [ 0.2484  , 0.707276],[ 0.127259, 0.750044],[ 0       , 0.76447 ],
    [-0.127259, 0.750044],[-0.2484  , 0.707276],[-0.358229, 0.636924],
    [-0.451556, 0.53975 ],[-0.504797, 0.443762],[-0.547291, 0.343077],
    [-0.578605, 0.238423],[-0.598311, 0.130528],[-0.648009, 0.037218],
    [-0.747183, 0       ],[-0.747183,-0.5]];
pf_T2_5=   [[-0.839258,-0.5     ],[-0.839258, 0       ],[-0.770246, 0.021652],
    [-0.726369, 0.079022],[-0.529167, 0.620889],[-0.485025, 0.67826 ],
    [-0.416278, 0.699911],[ 0.416278, 0.699911],[ 0.484849, 0.67826 ],
    [ 0.528814, 0.620889],[ 0.726369, 0.079022],[ 0.770114, 0.021652],
    [ 0.839258, 0       ],[ 0.839258,-0.5]];
pf_T5= 	  [[-1.632126,-0.5     ],[-1.632126, 0       ],[-1.568549, 0.004939],
    [-1.507539, 0.019367],[-1.450023, 0.042686],[-1.396912, 0.074224],
    [-1.349125, 0.113379],[-1.307581, 0.159508],[-1.273186, 0.211991],
    [-1.246868, 0.270192],[-1.009802, 0.920362],[-0.983414, 0.978433],
    [-0.949018, 1.030788],[-0.907524, 1.076798],[-0.859829, 1.115847],
    [-0.80682 , 1.147314],[-0.749402, 1.170562],[-0.688471, 1.184956],
    [-0.624921, 1.189895],[ 0.624971, 1.189895],[ 0.688622, 1.184956],
    [ 0.749607, 1.170562],[ 0.807043, 1.147314],[ 0.860055, 1.115847],
    [ 0.907754, 1.076798],[ 0.949269, 1.030788],[ 0.9837  , 0.978433],
    [ 1.010193, 0.920362],[ 1.246907, 0.270192],[ 1.273295, 0.211991],
    [ 1.307726, 0.159508],[ 1.349276, 0.113379],[ 1.397039, 0.074224],
    [ 1.450111, 0.042686],[ 1.507589, 0.019367],[ 1.568563, 0.004939],
    [ 1.632126, 0       ],[ 1.632126,-0.5]];
pf_T10=    [[-3.06511 ,-1       ],[-3.06511 , 0       ],[-2.971998, 0.007239],
    [-2.882718, 0.028344],[-2.79859 , 0.062396],[-2.720931, 0.108479],
    [-2.651061, 0.165675],[-2.590298, 0.233065],[-2.539962, 0.309732],
    [-2.501371, 0.394759],[-1.879071, 2.105025],[-1.840363, 2.190052],
    [-1.789939, 2.266719],[-1.729114, 2.334109],[-1.659202, 2.391304],
    [-1.581518, 2.437387],[-1.497376, 2.47144 ],[-1.408092, 2.492545],
    [-1.314979, 2.499784],[ 1.314979, 2.499784],[ 1.408091, 2.492545],
    [ 1.497371, 2.47144 ],[ 1.581499, 2.437387],[ 1.659158, 2.391304],
    [ 1.729028, 2.334109],[ 1.789791, 2.266719],[ 1.840127, 2.190052],
    [ 1.878718, 2.105025],[ 2.501018, 0.394759],[ 2.539726, 0.309732],
    [ 2.59015 , 0.233065],[ 2.650975, 0.165675],[ 2.720887, 0.108479],
    [ 2.798571, 0.062396],[ 2.882713, 0.028344],[ 2.971997, 0.007239],
    [ 3.06511 , 0       ],[ 3.06511 ,-1]];
pf_MXL=    [[-0.660421,-0.5     ],[-0.660421, 0       ],[-0.621898, 0.006033],
    [-0.587714, 0.023037],[-0.560056, 0.049424],[-0.541182, 0.083609],
    [-0.417357, 0.424392],[-0.398413, 0.458752],[-0.370649, 0.48514 ],
    [-0.336324, 0.502074],[-0.297744, 0.508035],[ 0.297744, 0.508035],
    [ 0.336268, 0.502074],[ 0.370452, 0.48514 ],[ 0.39811 , 0.458752],
    [ 0.416983, 0.424392],[ 0.540808, 0.083609],[ 0.559752, 0.049424],
    [ 0.587516, 0.023037],[ 0.621841, 0.006033],[ 0.660421, 0       ],
    [ 0.660421,-0.5]];


added temp for tests

added temp for tests

use <../scad/brackets.scad>

//rotate_y_at(90, [10,10])
  angle_corner_connector();

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