main: fix bad iteration (i,j) variable names

use <thing_libutils/metric-screw.scad>
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
include <thing_libutils/transforms.scad>;
include <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 <misc.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>
include <gantry-upper-connector.scad>
include <psu.scad>
use <rod-clamps.scad>

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

axis_pos_x = -213/2*mm;
axis_pos_y = 0*mm;
axis_range_z=[98*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;
            translate([-main_width/2-zrod_offset+xaxis_end_motor_offset[0], xaxis_zaxis_distance_y, 0])
                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]);
        }

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

        // x smooth 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])
                xaxis_end(with_motor=x==-1, show_nut=true, show_motor=true, show_nut=true);
            }
        }
    }
}

module y_axis()
{
    // y axis
    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)
    {
        yaxis_idler();
        attach(yaxis_idler_conn_pulleyblock, yaxis_idler_pulleyblock_conn)
        {
            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]);
            }
        }
    }

    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])
        {
            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]])
        {
            /*translate([x*yaxis_carriage_size[0]/2, y*(yaxis_carriage_size[1]-16*mm)/2, 0])*/
            // y axis plate
            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-16*mm), y*(yaxis_carriage_size[1]/2-16*mm), 0])
                {
                    cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);
                }
            }

            cubea([yaxis_carriage_size[0]-16*mm*2,yaxis_carriage_size[1]-16*mm*2, yaxis_carriage_size[2]], align=[0,0,1]);

            translate([0,0,10*mm])
                cubea(yaxis_carriage_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])
            {
                gantry_upper_connector();

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

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

                    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
                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()
{
    color(extrusion_color)
    gantry_lower();

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

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

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

    if(!preview_mode)
    {
        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()
{
    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]);
        }
    }
}

module gantry_lower()
{
    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]);
        }
    }
}

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>;
include <thing_libutils/transforms.scad>;
include <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 <misc.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>
include <gantry-upper-connector.scad>
include <psu.scad>
use <rod-clamps.scad>

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

axis_pos_x = -213/2*mm;
axis_pos_y = 0*mm;
axis_range_z=[98*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;
            translate([-main_width/2-zrod_offset+xaxis_end_motor_offset[0], xaxis_zaxis_distance_y, 0])
                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]);
        }

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

        // x smooth 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])
                xaxis_end(with_motor=x==-1, show_nut=true, show_motor=true, show_nut=true);
            }
        }
    }
}

module y_axis()
{
    // y axis
    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)
    {
        yaxis_idler();
        attach(yaxis_idler_conn_pulleyblock, yaxis_idler_pulleyblock_conn)
        {
            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]);
            }
        }
    }

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

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

            for(j=[-1,1])
            {
                attach([[0,j*(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]])
        {
            /*translate([x*yaxis_carriage_size[0]/2, y*(yaxis_carriage_size[1]-16*mm)/2, 0])*/
            // y axis plate
            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-16*mm), y*(yaxis_carriage_size[1]/2-16*mm), 0])
                {
                    cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);
                }
            }

            cubea([yaxis_carriage_size[0]-16*mm*2,yaxis_carriage_size[1]-16*mm*2, yaxis_carriage_size[2]], align=[0,0,1]);

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

}

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

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

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

                    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([i*(zmotor_mount_rod_offset_x),0,0])
            {
                // z rods
                translate([0,0,zaxis_motor_offset_z-50])
                    cylindera(h=zaxis_rod_l,d=zaxis_rod_d, align=[0,0,1]);

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

            }
        }
    }

}

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

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

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

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

    if(!preview_mode)
    {
        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()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    {
        if(preview_mode)
        {
            cubea(size=[extrusion_size, extrusion_size, main_height], align=[-i,0,1]);
        }
        else
        {
            linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);
        }
    }

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

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

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

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

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

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

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

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

/*psu();*/

/*%enclosure();*/


added 2 instances by default

added 2 instances by default


triangles: Add copy of Triangles.scad

triangles: Add copy of Triangles.scad

From https://github.com/tkoopman/Delta-Diamond/blob/master/OpenSCAD/Triangles.scad

/*
Triangles.scad
 Author: Tim Koopman
 https://github.com/tkoopman/Delta-Diamond/blob/master/OpenSCAD/Triangles.scad

         angleCA
           /|\
        a / H \ c
         /  |  \
 angleAB ------- angleBC
            b

Standard Parameters
	center: true/false
		If true same as centerXYZ = [true, true, true]

	centerXYZ: Vector of 3 true/false values [CenterX, CenterY, CenterZ]
		center must be left undef

	height: The 3D height of the Triangle. Ignored if heights defined

	heights: Vector of 3 height values heights @ [angleAB, angleBC, angleCA]
		If CenterZ is true each height will be centered individually, this means
		the shape will be different depending on CenterZ. Most times you will want
		CenterZ to be true to get the shape most people want.
*/

/*
Triangle
	a: Length of side a
	b: Length of side b
	angle: angle at point angleAB
*/
module Triangle(
			a, b, angle, height=1, heights=undef,
			center=undef, centerXYZ=[false,false,false])
{
	// Calculate Heights at each point
	heightAB = ((heights==undef) ? height : heights[0])/2;
	heightBC = ((heights==undef) ? height : heights[1])/2;
	heightCA = ((heights==undef) ? height : heights[2])/2;
	centerZ = (center || (center==undef && centerXYZ[2]))?0:max(heightAB,heightBC,heightCA);

	// Calculate Offsets for centering
	offsetX = (center || (center==undef && centerXYZ[0]))?((cos(angle)*a)+b)/3:0;
	offsetY = (center || (center==undef && centerXYZ[1]))?(sin(angle)*a)/3:0;

	pointAB1 = [-offsetX,-offsetY, centerZ-heightAB];
	pointAB2 = [-offsetX,-offsetY, centerZ+heightAB];
	pointBC1 = [b-offsetX,-offsetY, centerZ-heightBC];
	pointBC2 = [b-offsetX,-offsetY, centerZ+heightBC];
	pointCA1 = [(cos(angle)*a)-offsetX,(sin(angle)*a)-offsetY, centerZ-heightCA];
	pointCA2 = [(cos(angle)*a)-offsetX,(sin(angle)*a)-offsetY, centerZ+heightCA];

	polyhedron(
		points=[	pointAB1, pointBC1, pointCA1,
					pointAB2, pointBC2, pointCA2 ],
		triangles=[
			[0, 1, 2],
			[3, 5, 4],
			[0, 3, 1],
			[1, 3, 4],
			[1, 4, 2],
			[2, 4, 5],
			[2, 5, 0],
			[0, 5, 3] ] );
}

/*
Isosceles Triangle
	Exactly 2 of the following paramaters must be defined.
	If all 3 defined H will be ignored.
	b: length of side b
	angle: angle at points angleAB & angleBC.
*/
module Isosceles_Triangle(
			b, angle, H=undef, height=1, heights=undef,
			center=undef, centerXYZ=[true, false, false])
{
	valid = 	(angle!=undef)?((angle < 90) && (b!=undef||H!=undef)) : (b!=undef&&H!=undef);
	ANGLE = (angle!=undef) ? angle : atan(H / (b/2));
	a = (b==undef)?(H/sin((180-(angle*2))/2)) :
		 (b / cos(ANGLE))/2;
	B = (b==undef)? (cos(angle)*a)*2:b;
	if (valid)
	{
		Triangle(a=a, b=B, angle=ANGLE, height=height, heights=heights,
					center=center, centerXYZ=centerXYZ);
	} else {
		echo("Invalid Isosceles_Triangle. Must specify any 2 of b, angle and H, and if angle used angle must be less than 90");
	}
}

/*
Right Angled Triangle
	Create a Right Angled Triangle where the hypotenuse will be calculated.

       |\
      a| \
       |  \
       ----
         b
	a: length of side a
	b: length of side b
*/
module Right_Angled_Triangle(
			a, b, height=1, heights=undef,
			center=undef, centerXYZ=[false, false, false])
{
	Triangle(a=a, b=b, angle=90, height=height, heights=heights,
				center=center, centerXYZ=centerXYZ);
}

/*
Wedge
	Is same as Right Angled Triangle with 2 different heights, and rotated.
	Good for creating support structures.
*/
module Wedge(a, b, w1, w2)
{
	rotate([90,0,0])
		Right_Angled_Triangle(a, b, heights=[w1, w2, w1], centerXYZ=[false, false, true]);
}

/*
Equilateral Triangle
	Create a Equilateral Triangle.

	l: Length of all sides (a, b & c)
	H: Triangle size will be based on the this 2D height
		When using H, l is ignored.
*/
module Equilateral_Triangle(
			l=10, H=undef, height=1, heights=undef,
			center=undef, centerXYZ=[true,false,false])
{
	L = (H==undef)?l:H/sin(60);
	Triangle(a=L,b=L,angle=60,height=height, heights=heights,
				center=center, centerXYZ=centerXYZ);
}

/*
Trapezoid
	Create a Basic Trapezoid (Based on Isosceles_Triangle)

            d
          /----\
         /  |   \
     a  /   H    \ c
       /    |     \
 angle ------------ angle
            b

	b: Length of side b
	angle: Angle at points angleAB & angleBC
	H: The 2D height at which the triangle should be cut to create the trapezoid
	heights: If vector of size 3 (Standard for triangles) both cd & da will be the same height, if vector have 4 values [ab,bc,cd,da] than each point can have different heights.
*/
module Trapezoid(
			b, angle=60, H, height=1, heights=undef,
			center=undef, centerXYZ=[true,false,false])
{
	validAngle = (angle < 90);
	adX = H / tan(angle);

	// Calculate Heights at each point
	heightAB = ((heights==undef) ? height : heights[0])/2;
	heightBC = ((heights==undef) ? height : heights[1])/2;
	heightCD = ((heights==undef) ? height : heights[2])/2;
	heightDA = ((heights==undef) ? height : ((len(heights) > 3)?heights[3]:heights[2]))/2;

	// Centers
	centerX = (center || (center==undef && centerXYZ[0]))?0:b/2;
	centerY = (center || (center==undef && centerXYZ[1]))?0:H/2;
	centerZ = (center || (center==undef && centerXYZ[2]))?0:max(heightAB,heightBC,heightCD,heightDA);

	// Points
	y = H/2;
	bx = b/2;
	dx = (b-(adX*2))/2;

	pointAB1 = [centerX-bx, centerY-y, centerZ-heightAB];
	pointAB2 = [centerX-bx, centerY-y, centerZ+heightAB];
	pointBC1 = [centerX+bx, centerY-y, centerZ-heightBC];
	pointBC2 = [centerX+bx, centerY-y, centerZ+heightBC];
	pointCD1 = [centerX+dx, centerY+y, centerZ-heightCD];
	pointCD2 = [centerX+dx, centerY+y, centerZ+heightCD];
	pointDA1 = [centerX-dx, centerY+y, centerZ-heightDA];
	pointDA2 = [centerX-dx, centerY+y, centerZ+heightDA];

	validH = (adX < b/2);

	if (validAngle && validH)
	{
		polyhedron(
			points=[	pointAB1, pointBC1, pointCD1, pointDA1,
						pointAB2, pointBC2, pointCD2, pointDA2 ],
			triangles=[
				[0, 1, 2],
				[0, 2, 3],
				[4, 6, 5],
				[4, 7, 6],
				[0, 4, 1],
				[1, 4, 5],
				[1, 5, 2],
				[2, 5, 6],
				[2, 6, 3],
				[3, 6, 7],
				[3, 7, 0],
				[0, 7, 4]	] );
	} else {
		if (!validAngle) echo("Trapezoid invalid, angle must be less than 90");
		else echo("Trapezoid invalid, H is larger than triangle");
	}
}

// Examples
Triangle(a=5, b=15, angle=33, centerXYZ=[true,false,false]);
translate([20,0,0]) Right_Angled_Triangle(a=5, b=20, centerXYZ=[false,true,false]);
translate([45,0,0]) Wedge(a=5, b=20, w1=10, w2=5);
translate([-20,0,0]) Trapezoid(b=20, angle=33, H=4, height=5, centerXYZ=[true,false,true]);

translate([0,10,0]) Isosceles_Triangle(b=20, angle=33);
translate([30,10,0]) Isosceles_Triangle(b=20, H=5);
translate([-30,10,0]) Isosceles_Triangle(angle=33, H=5, center=true);

translate([15,-25,0]) Equilateral_Triangle(l=20);
translate([-15,-25,0]) Equilateral_Triangle(H=20);


Add a few comments

Add a few comments

tube_diameter = 28;
margin = 1 ;
thickness	    =1;
width = 15;
beam_size = 10;
beam_thickness = 5;
clip_width=10;

difference(){
	union(){
		// Cylinder
		rotate([90,0,0]) cylinder(r=tube_diameter/2+thickness+margin, h = width, center=true);

		// Top flat part
		translate([0, 0, beam_thickness]) cube(size=[beam_size+2*thickness, width, tube_diameter+2*thickness], 	center = true);

		// Part to block strap
		translate([0, width/2-(width-clip_width)/4, 0]) hull(){
		rotate([90,0,0]) cylinder(r=tube_diameter/2+thickness+margin+1, h = (width-clip_width)/2, center=true);
		translate([0, 0, beam_thickness+1]) cube(size=[beam_size+2*thickness, (width-clip_width)/2, tube_diameter+2*thickness], center = true);
		}

		// Second part to block strap
		translate([0, -width/2+(width-clip_width)/4, 0]) hull(){
		rotate([90,0,0]) cylinder(r=tube_diameter/2+thickness+margin+1, h = (width-clip_width)/2, center=true);
		translate([0, 0, beam_thickness+1]) cube(size=[beam_size+2*thickness, (width-clip_width)/2, tube_diameter+2*thickness], center = true);
		}
	}

	// Place for beam
	translate([0, 0, tube_diameter/2+thickness*2+beam_thickness/2+1]) cube(size=[beam_size, 2*width, beam_thickness+2], center = true);

	// Cylinder corresponding to space for bar
	rotate([90,0,0]) cylinder(r=tube_diameter/2+margin, h = 2*width, center=true);

	// Cube to hide bottom
	translate([0, 0, -tube_diameter*5/8]) cube(size=[2*tube_diameter, 2*width, tube_diameter*2], center=true);

}

tube_diameter = 28;
margin = 1 ;
thickness	    =1;
width = 15;
beam_size = 10;
beam_thickness = 5;

clip_width=10;
difference(){
union(){
union(){
rotate([90,0,0]) cylinder(r=tube_diameter/2+thickness+margin, h = width, center=true);
translate([0, 0, beam_thickness]) cube(size=[beam_size+2*thickness, width, tube_diameter+2*thickness], center = true);
}

translate([0, width/2-(width-clip_width)/4, 0]) hull(){
rotate([90,0,0]) cylinder(r=tube_diameter/2+thickness+margin+1, h = (width-clip_width)/2, center=true);
translate([0, 0, beam_thickness+1]) cube(size=[beam_size+2*thickness, (width-clip_width)/2, tube_diameter+2*thickness], center = true);
}
translate([0, -width/2+(width-clip_width)/4, 0]) hull(){
rotate([90,0,0]) cylinder(r=tube_diameter/2+thickness+margin+1, h = (width-clip_width)/2, center=true);
translate([0, 0, beam_thickness+1]) cube(size=[beam_size+2*thickness, (width-clip_width)/2, tube_diameter+2*thickness], center = true);
}
}
translate([0, 0, tube_diameter/2+thickness*2+beam_thickness/2+1]) cube(size=[beam_size, 2*width, beam_thickness+2], center = true);
rotate([90,0,0]) cylinder(r=tube_diameter/2+margin, h = 2*width, center=true);
translate([0, 0, -tube_diameter*5/8]) cube(size=[2*tube_diameter, 2*width, tube_diameter*2], center=true);

}


added rpi w (zero) holder

added rpi w (zero) holder


1 box by default

1 box by default

use <junction_box.scad>;

for(i = [0:0])
  translate(i*[0, 83, 0])
    junction_box();

use <junction_box.scad>;

for(i = [0:2])
  translate(i*[0, 83, 0])
    junction_box();


Add top model

Add top model

tol = 0.5;
pcb_x = 130;
pcb_y = 110;
pcb_z = 4;
bolt_d = 3.6;
shift_bolt = 5;

// box thickness
th = 3;

shift_x = th + 1;
shift_y = th + 1;

box_x = pcb_x + shift_x + th + 1;
box_y = pcb_y + 2*th + 1;

pcb_width = 2;
pcb_up = 9;

box_z = th + pcb_up + pcb_width - 1;

socket_h = 15;
socket_w = 10;
socket_n = 5;
socket_int = 20;
start_socket_x = 20 + shift_x;
start_socket_z = th + pcb_z + tol;
eps = 1e-1;

usb_type_b_w = 15.2;
usb_type_b_h = 11;
start_type_b_y = shift_y + pcb_y - 30.1;
//start_type_b_z = th + pcb_z + tol;

usb_type_a_w = 17.3;
usb_type_a_h = 7;
//usb_type_a_h = 0.5;
start_type_a_y = shift_y + 44.7;
//start_type_a_z = th + pcb_z + tol;

// programmator
micro_x = 10;
micro_y = 21.1;
micro_start_x = shift_x + 4.75;
micro_start_y = shift_y + pcb_y - 23.3 - micro_y;

contrast_start_x = shift_x + 38.4;
contrast_start_y = shift_y + 25.7;
volume_start_x = shift_x + pcb_x - 39.2;
volume_start_y = contrast_start_y;
pot_d = 7;
under_pcb = 12.5;
fn = 10;
gaika_h = 6;
gaika_w = 5.6;

translate([0,0,-50]) {

difference() {
  union() {
    difference() {
      cube([box_x,box_y,box_z], false);
      translate([th, th, th]) {
        cube([box_x-2*th+eps, box_y-2*th+eps, box_z-th+eps], false);
      }
    }
    // under_pcb
    for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
      for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
        translate([dx,dy,pcb_up/2+th-eps]) {
          cube(size=[under_pcb,under_pcb,pcb_up], center=true);
        }
      }
    }
  }

  // bolts
  for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
    for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
      translate([dx,dy,-eps]) {
        cylinder($fn=fn, r=bolt_d/2, h=th+pcb_up+2*eps);
        // gaika
        cylinder($fn=6, r=gaika_w / 2 / cos(30) + 0.05, h=gaika_h);
      }
    }
  }

//    for (i = [0:1:socket_n-1]) {
//        translate([start_socket_x+i*socket_int-tol, box_y-th-eps, start_socket_z]) {
//            cube(size=[socket_w+2*tol, th+2*eps, box_z]);
//        }
//    }

//    // usb_in1 type b
//    translate([box_x-th-eps, start_type_b_y-tol, start_type_b_z]) {
//        cube(size=[th+2*eps, usb_type_b_w+2*tol, box_z]);
//    }

//    // usb_out1 type a
//    translate([-eps, start_type_a_y - tol, start_type_a_z]) {
//        cube(size=[th+2*eps, usb_type_a_w + 2*tol, box_z]);
//    }

    // programmator
    translate([micro_start_x-tol,micro_start_y-tol, -eps]) {
      cube(size=[micro_x+2*tol, micro_y+2*tol, th+2*eps]);
    }

    // contrast
    translate([contrast_start_x, contrast_start_y, -eps]) {
      cylinder($fn=fn, r=pot_d/2, h=th+2*eps);
    }

    // volume
//    translate([volume_start_x, volume_start_y, -eps]) {
//      cylinder($fn=20, r=pot_d/2, h=th+2*eps);
//    }
}
}

top_box_z = 17 + th;
stoiki_r = bolt_d/2 + 2;
pcb_room = 0.5;
screen_start_x = shift_x + 28;
screen_start_y = shift_y + 40;
screen_length_x = 72;
screen_length_y = 24;
screen_hold_x = 40;
screen_hold_y = 4;
screen_hold_start_z = 14;
screen_hold_y_shift = -2;

// TODO
master_button_y = shift_y + 10;
master_button_x = shift_x + 43;
master_button_int = 21.8;
master_button_r = 3;
// TODO
top_bolt_h = 2;
top_bolt_r = gaika_w / 2 / cos(30) + 0.05;

difference() {
  union() {
    difference() {
      cube([box_x,box_y,top_box_z], false);
      translate([th, th, -eps]) {
        cube([box_x-2*th+eps, box_y-2*th+eps, top_box_z-th+eps], false);
      }
    }
    // stoiki
    for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
      for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
        translate([dx,dy,pcb_room]) {
	  cylinder($fn=fn, r=stoiki_r, h=top_box_z-th+eps);
        }
      }
    }
    // screen_hold
    translate([screen_start_x + (screen_length_x - screen_hold_x)/2, screen_start_y + screen_hold_y_shift - screen_hold_y, screen_hold_start_z]) {
	cube([screen_hold_x, screen_hold_y, top_box_z - screen_hold_start_z - th + eps]);
    }
  }
  // bolts
  for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
    for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
      translate([dx,dy,-eps]) {
        cylinder($fn=fn, r=bolt_d/2, h=top_box_z+2*eps);
      }
      translate([dx, dy, top_box_z - top_bolt_h]) {
        cylinder($fn=fn, r=top_bolt_r, h=top_bolt_h + eps);
      }
    }
  }

  // screen
  translate([screen_start_x-tol, screen_start_y-tol, top_box_z - th - eps]) {
      cube([screen_length_x + 2*tol, screen_length_y + 2*tol, th + 2*eps]);
  }
  // sockets
  for (i = [0:1:socket_n-1]) {
      translate([start_socket_x+i*socket_int-tol, box_y-th-eps, -eps]) {
	  cube(size=[socket_w+2*tol, th+2*eps, socket_h+tol]);
      }
  }
  // type_b
  translate([box_x - th - eps, start_type_b_y - tol, -tol]) {
      cube([th + 2*eps, usb_type_b_w + 2*tol, usb_type_b_h + 2*tol]);
  }
  // type_a
  translate([-eps, start_type_a_y - tol, -tol]) {
      cube([th + 2*eps, usb_type_a_w + 2*tol, usb_type_a_h + 2*tol]);
  }
  // master buttons
  for (dx = [master_button_x, master_button_x + master_button_int*2])
      translate([dx, master_button_y, top_box_z - th - eps]) {
	  cylinder($fn=fn, r=master_button_r+tol, h=th+2*eps);
      }
}

//// bolts
//for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
//  for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
//    difference() {
//      translate([dx,dy,pcb_up/2+th]) {
//        cube(size=[a,a,pcb_up], center=true);
//      }
//      translate([dx,dy,-eps]) {
//        cylinder($fn=20, r=bolt_d/2, h=th+pcb_up+2*eps);
//      }
//    }
//  }
//}

//leg_r = t;
//shift = t/2+leg_r;
//for (dx = [shift, a-shift])
//    for (dy = [shift, b-shift]) {
//        translate([dx, dy, 0]) {
//            cylinder(h=c, r=leg_r, $fn=40);
//        }
//    }

tol = 0.5;
pcb_x = 130;
pcb_y = 110;
pcb_z = 4;
bolt_d = 3.6;
shift_bolt = 5;

// box thickness
th = 3;

shift_x = th + 1;
shift_y = th + 1;

box_x = pcb_x + shift_x + th + 1;
box_y = pcb_y + 2*th + 1;

pcb_width = 2;
pcb_up = 9;

box_z = th + pcb_up + pcb_width - 1;

//socket_h = 15;
socket_w = 10;
socket_n = 5;
socket_int = 20;
start_socket_x = 20 + shift_x;
start_socket_z = th + pcb_z + tol;
eps = 1e-1;

usb_type_b_w = 15.2;
//usb_type_b_h = 3;
start_type_b_y = shift_y + pcb_y - 30.1;
start_type_b_z = th + pcb_z + tol;

usb_type_a_w = 17.3;
//usb_type_a_h = 0.5;
start_type_a_y = shift_y + 44.7;
start_type_a_z = th + pcb_z + tol;

// programmator
micro_x = 10;
micro_y = 21.1;
micro_start_x = shift_x + 4.75;
micro_start_y = shift_y + pcb_y - 23.3 - micro_y;

contrast_start_x = shift_x + 38.4;
contrast_start_y = shift_y + 25.7;
volume_start_x = shift_x + pcb_x - 39.2;
volume_start_y = contrast_start_y;
pot_d = 7;
under_pcb = 12.5;
fn = 10;
gaika_h = 6;
gaika_w = 5.5;

difference() {
  union() {
    difference() {
      cube([box_x,box_y,box_z], false);
      translate([th, th, th]) {
        cube([box_x-2*th+eps, box_y-2*th+eps, box_z-th+eps], false);
      }
    }
    // under_pcb
    for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
      for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
        translate([dx,dy,pcb_up/2+th-eps]) {
          cube(size=[under_pcb,under_pcb,pcb_up], center=true);
        }
      }
    }
  }

  // bolts
  for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
    for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
      translate([dx,dy,-eps]) {
        cylinder($fn=fn, r=bolt_d/2, h=th+pcb_up+2*eps);
        // gaika
        cylinder($fn=6, r=gaika_w / 2 / cos(30) + 0.05, h=gaika_h);
      }
    }
  }

//    for (i = [0:1:socket_n-1]) {
//        translate([start_socket_x+i*socket_int-tol, box_y-th-eps, start_socket_z]) {
//            cube(size=[socket_w+2*tol, th+2*eps, box_z]);
//        }
//    }

//    // usb_in1 type b
//    translate([box_x-th-eps, start_type_b_y-tol, start_type_b_z]) {
//        cube(size=[th+2*eps, usb_type_b_w+2*tol, box_z]);
//    }

//    // usb_out1 type a
//    translate([-eps, start_type_a_y - tol, start_type_a_z]) {
//        cube(size=[th+2*eps, usb_type_a_w + 2*tol, box_z]);
//    }

    // programmator
    translate([micro_start_x-tol,micro_start_y-tol, -eps]) {
      cube(size=[micro_x+2*tol, micro_y+2*tol, th+2*eps]);
    }

    // contrast
    translate([contrast_start_x, contrast_start_y, -eps]) {
      cylinder($fn=fn, r=pot_d/2, h=th+2*eps);
    }

    // volume
//    translate([volume_start_x, volume_start_y, -eps]) {
//      cylinder($fn=20, r=pot_d/2, h=th+2*eps);
//    }
};

//// bolts
//for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
//  for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
//    difference() {
//      translate([dx,dy,pcb_up/2+th]) {
//        cube(size=[a,a,pcb_up], center=true);
//      }
//      translate([dx,dy,-eps]) {
//        cylinder($fn=20, r=bolt_d/2, h=th+pcb_up+2*eps);
//      }
//    }
//  }
//}

//leg_r = t;
//shift = t/2+leg_r;
//for (dx = [shift, a-shift])
//    for (dy = [shift, b-shift]) {
//        translate([dx, dy, 0]) {
//            cylinder(h=c, r=leg_r, $fn=40);
//        }
//    }


add cad for dome motor

add cad for dome motor

// JohK nutsnbolts library
include <../nutsnbolts/cyl_head_bolt.scad>

// all measures in mm
d = 10;
thickness = 2;
do = d+2*thickness;
thickness_mount = 4; // additional to thickness
h = 60+thickness;
clr = 0.3; // clearance of cutouts
screw = "M4";

module holder() {
     // make the half of the bracket square to lay flat on the thing to mount to
     cube(size=[do,do/2,h]);

     // the rest round to spare filament
     translate([do/2,do/2,0])
          cylinder(h,do/2,do/2);
}

module shaft_hole() {
     translate([do/2,do/2,thickness])
          cylinder(h,d/2+clr,d/2+clr);
     translate([-clr,0,10])
          cube(size=[do+2*clr,do+clr,h-2*10]);
}

module base() {
     difference() {
          cube(size=[do,thickness_mount,h]);

          // nut-catch for mounting bracket
          translate([do/2,5,8]) rotate([-90,0,0])
               nutcatch_parallel(screw, l=20, clk=clr, clh=clr, clsl=clr);
          translate([do/2,5,h-8]) rotate([-90,0,0])
               nutcatch_parallel(screw, l=20, clk=clr, clh=clr, clsl=clr);
     }

     translate([0,thickness_mount,0])
          difference() {
          holder();
          shaft_hole();
     }
}

module shaft() {
     difference() {
          translate([0,0,thickness])
               cylinder(h-thickness,d/2,d/2);

          // nut-catch for mounting motor
          translate([0,0,18]) rotate([90,0,0])
               nutcatch_parallel(screw, l=20, clk=clr, clh=clr, clsl=clr);
          translate([0,0,h-18]) rotate([90,0,0])
               nutcatch_parallel(screw, l=20, clk=clr, clh=clr, clsl=clr);
     }
}

{
     color("red")
          base();

     translate([do/2,do/2+thickness_mount,0])
          shaft();
}

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


Add logo2 OpenSCAD file

Add logo2 OpenSCAD file

cube([72,22,4]);

translate([1,10,4])
{
    linear_extrude(height = 2.5)
    {
        color(c = [1,0,0], alpha = 1.0){
        text(text="#Sodalicious", spacing=0.9, font="Arial");
        }
    }
}
translate([1,2,4]) {
    linear_extrude(height = 2.5)
    {
        color(c = [1,0,0], alpha = 1.0){
        text(text="British Mixing Technology", spacing=0.9, font="Arial", size=5);
        }
    }
}

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


fixup! *: use undef/U alias

fixup! *: use undef/U alias

XAXIS = [1,0,0];
YAXIS = [0,1,0];
ZAXIS = [0,0,1];
NAXIS = [0,0,0];

X = XAXIS;
Y = YAXIS;
Z = ZAXIS;
N = NAXIS;

AXES = [X,Y,Z];

U = undef;

function get(key, dict) =
    let(x = search(key, dict))
    let(kv = dict[x[0]])
    kv[1];

XAXIS = [1,0,0];
YAXIS = [0,1,0];
ZAXIS = [0,0,1];
NAXIS = [0,0,0];

X = XAXIS;
Y = YAXIS;
Z = ZAXIS;
N = NAXIS;

AXES = [X,Y,Z];

U = U;

function get(key, dict) =
    let(x = search(key, dict))
    let(kv = dict[x[0]])
    kv[1];


Add a flange to the bottom of the bumper to make it a bit stiffer. Should help with direct contacts on the front

/* Pins required -

pintack(side=true, h=7.8+2+2.5, bh=2);

*/

// TODO: The locations of these connectors are just horrible and too "magic"
Bumper_Con_LeftMicroSwitch =
[
	zr3Vect(   [(-10 + dw + 9.6 +.25), (BaseDiameter/2 - 16 + 4 + dw + 1.25 + .5), dw], 43.5    ),
	[0, 0, 1],
	43.5,
	0,
	0];

Bumper_Con_RightMicroSwitch =
[
	[ -zr3Vect([(-10 + dw + 9.6 +.25), (BaseDiameter/2 - 16 + 4 + dw + 1.25 + .5), dw], 43.5)[0],
	  zr3Vect([(-10 + dw + 9.6 +.25), (BaseDiameter/2 - 16 + 4 + dw + 1.25 + .5), dw], 43.5)[1],
	  zr3Vect([(-10 + dw + 9.6 +.25), (BaseDiameter/2 - 16 + 4 + dw + 1.25 + .5), dw], 43.5)[2] ],
	[0, 0, 1],
	-43.5,
	0,
	0];

Bumper_Con_LeftPin =
[
	zr3Vect(   [(-10 + 15.7 ), (BaseDiameter/2 - 16 + -7 + 2.65 ), dw + 5.8 + dw], 43.5    ),
	[0, 0, 1],
	43.5,
	0,
	0];

Bumper_Con_RightPin =
[
	[ -zr3Vect(   [(-10 + 15.7 ), (BaseDiameter/2 - 16 + -7 + 2.65 ), dw + 5.8 + dw], 43.5    )[0],
	  zr3Vect(   [(-10 + 15.7 ), (BaseDiameter/2 - 16 + -7 + 2.65 ), dw + 5.8 + dw], 43.5    )[1],
	  zr3Vect(   [(-10 + 15.7 ), (BaseDiameter/2 - 16 + -7 + 2.65 ), dw + 5.8 + dw], 43.5    )[2] ],
	[0, 0, 1],
	-43.5,
	0,
	0];

module Bumper_STL()
{
	printedPart("printedparts/Bumper.scad", "Bumper", "Bumper_STL()") {

	    view(t=[1, -8, -11], r=[52, 0, 23], d=184);

		if (DebugCoordinateFrames) frame();
		if (DebugConnectors) {
			connector(Bumper_Con_LeftMicroSwitch);
			connector(Bumper_Con_RightMicroSwitch);
			connector(Bumper_Con_LeftPin);
			connector(Bumper_Con_RightPin);
		}

		color(Level2PlasticColor) {
			if (UseSTL) {
				import(str(STLPath, "Bumper.stl"));
			} else {
				BumperModel();
			}
		}
	}
}

module BumperModel()
{
	// Parameters
	thickness = dw;				// bumper thickness
	height = 15;				// bumper height
	offset = 5;					// distance from base to inside of bumper
	wrapAngle = 170;			// angle that bumper wraps around
	microSwitchAngle = 43.5;	// angle that microswitches are placed at

	bumpstopWidth = 8;			// width of little block that sticks out to hit the microswitch
	bumpstopHeight = 5;			// height of little block that sticks out to hit the microswitch

	// Calculated parameters
	outr = BaseDiameter/2 + offset + thickness;		// outside radius of the bumper

    // Bumper flange
	rotate([0, 0, (180 - wrapAngle) / 2])
    difference() {
        linear_extrude(thickness*2)
            donutSector(outr, outr-thickness*2, wrapAngle);

        translate([0,0,thickness*2])
            rotate_extrude(convexity = 10)
                translate([outr-thickness*2,0,0])
                     circle(r=thickness);
    }

	// Bumper arc
	linear_extrude(height)
	rotate([0, 0, (180 - wrapAngle) / 2])
		donutSector(outr, outr - thickness, wrapAngle);

	// Connectors
	for(i=[0, 1])
	mirror([i, 0, 0])
	rotate([0, 0, microSwitchAngle])
	 {

		// Springy bits
		translate([15, BaseDiameter/2 - 11, 0])
		rotate([0, 0, -130])
		linear_extrude(5)
			donutSector(17, 17 - 2*perim, 175);

		// Bumpstops to hit microwitch arm
		translate([0, BaseDiameter/2 - 1 , 0])
			cube([bumpstopWidth, offset + 1 , bumpstopHeight]);

		// Microswitch plates
		translate([-10, BaseDiameter/2 - 16, 0])
			MicroSwitchPlate();
	}
}

module MicroSwitchPlate()
{
	// Parameters - todo: pickup from microswitch model?
	ms_length=12.9;
	ms_width=6.6;
	ms_height=5.8;

	base_length = ms_length + 0.5 + 2*dw;
	base_width = ms_width + 6.5;

	// Base
	cube([base_length, base_width, dw]);
	// Microswitch surround
	cube([dw, base_width, dw + 3]);
	translate([base_length - dw, 0, 0])
		cube([dw, base_width, dw + 3]);
	translate([0, 4, 0])
		cube([base_length, dw, dw + 2]);

	// Rear support lozenge with pin hole
	lozenge_height = dw + ms_height;

	translate([0, -7, 0])
	difference() {
		linear_extrude(lozenge_height)
		hull() {
			translate([2.5, 7])
				circle(r=2.5);
			translate([base_length, 9.5])
				circle(r=eta);
			translate([13, 1])
				circle(r=2.5);
			translate([20, 1])
				circle(r=2.5);
		}

		// Actual hole
		translate([15.7, 2.65, lozenge_height + dw])
		mirror([0, 0, 1])
			pinhole(fixed=true);
	}
}

// Rotate a 3vector v = [x,y,z] about the origin by ang degrees
function zr3Vect(v, ang) =
[
	v[0] * cos(ang) - v[1] * sin(ang),
	v[0] * sin(ang) + v[1] * cos(ang),
	v[2]
];

/* Pins required -

pintack(side=true, h=7.8+2+2.5, bh=2);

*/

// TODO: The locations of these connectors are just horrible and too "magic"
Bumper_Con_LeftMicroSwitch =
[
	zr3Vect(   [(-10 + dw + 9.6 +.25), (BaseDiameter/2 - 16 + 4 + dw + 1.25 + .5), dw], 43.5    ),
	[0, 0, 1],
	43.5,
	0,
	0];

Bumper_Con_RightMicroSwitch =
[
	[ -zr3Vect([(-10 + dw + 9.6 +.25), (BaseDiameter/2 - 16 + 4 + dw + 1.25 + .5), dw], 43.5)[0],
	  zr3Vect([(-10 + dw + 9.6 +.25), (BaseDiameter/2 - 16 + 4 + dw + 1.25 + .5), dw], 43.5)[1],
	  zr3Vect([(-10 + dw + 9.6 +.25), (BaseDiameter/2 - 16 + 4 + dw + 1.25 + .5), dw], 43.5)[2] ],
	[0, 0, 1],
	-43.5,
	0,
	0];

Bumper_Con_LeftPin =
[
	zr3Vect(   [(-10 + 15.7 ), (BaseDiameter/2 - 16 + -7 + 2.65 ), dw + 5.8 + dw], 43.5    ),
	[0, 0, 1],
	43.5,
	0,
	0];

Bumper_Con_RightPin =
[
	[ -zr3Vect(   [(-10 + 15.7 ), (BaseDiameter/2 - 16 + -7 + 2.65 ), dw + 5.8 + dw], 43.5    )[0],
	  zr3Vect(   [(-10 + 15.7 ), (BaseDiameter/2 - 16 + -7 + 2.65 ), dw + 5.8 + dw], 43.5    )[1],
	  zr3Vect(   [(-10 + 15.7 ), (BaseDiameter/2 - 16 + -7 + 2.65 ), dw + 5.8 + dw], 43.5    )[2] ],
	[0, 0, 1],
	-43.5,
	0,
	0];

module Bumper_STL()
{
	printedPart("printedparts/Bumper.scad", "Bumper", "Bumper_STL()") {

	    view(t=[1, -8, -11], r=[52, 0, 23], d=184);

		if (DebugCoordinateFrames) frame();
		if (DebugConnectors) {
			connector(Bumper_Con_LeftMicroSwitch);
			connector(Bumper_Con_RightMicroSwitch);
			connector(Bumper_Con_LeftPin);
			connector(Bumper_Con_RightPin);
		}

		color(Level2PlasticColor) {
			if (UseSTL) {
				import(str(STLPath, "Bumper.stl"));
			} else {
				BumperModel();
			}
		}
	}
}

module BumperModel()
{
	// Parameters
	thickness = dw;				// bumper thickness
	height = 15;				// bumper height
	offset = 5;					// distance from base to inside of bumper
	wrapAngle = 170;			// angle that bumper wraps around
	microSwitchAngle = 43.5;	// angle that microswitches are placed at

	bumpstopWidth = 8;			// width of little block that sticks out to hit the microswitch
	bumpstopHeight = 5;			// height of little block that sticks out to hit the microswitch

	// Calculated parameters
	outr = BaseDiameter/2 + offset + thickness;		// outside radius or the bumper

	// Bumper arc
	linear_extrude(height)
	rotate([0, 0, (180 - wrapAngle) / 2])
		donutSector(outr, outr - thickness, wrapAngle);

	// Connectors
	for(i=[0, 1])
	mirror([i, 0, 0])
	rotate([0, 0, microSwitchAngle])
	 {

		// Springy bits
		translate([15, BaseDiameter/2 - 11, 0])
		rotate([0, 0, -130])
		linear_extrude(5)
			donutSector(17, 17 - 2*perim, 175);

		// Bumpstops to hit microwitch arm
		translate([0, BaseDiameter/2 - 1 , 0])
			cube([bumpstopWidth, offset + 1 , bumpstopHeight]);

		// Microswitch plates
		translate([-10, BaseDiameter/2 - 16, 0])
			MicroSwitchPlate();
	}
}

module MicroSwitchPlate()
{
	// Parameters - todo: pickup from microswitch model?
	ms_length=12.9;
	ms_width=6.6;
	ms_height=5.8;

	base_length = ms_length + 0.5 + 2*dw;
	base_width = ms_width + 6.5;

	// Base
	cube([base_length, base_width, dw]);
	// Microswitch surround
	cube([dw, base_width, dw + 3]);
	translate([base_length - dw, 0, 0])
		cube([dw, base_width, dw + 3]);
	translate([0, 4, 0])
		cube([base_length, dw, dw + 2]);

	// Rear support lozenge with pin hole
	lozenge_height = dw + ms_height;

	translate([0, -7, 0])
	difference() {
		linear_extrude(lozenge_height)
		hull() {
			translate([2.5, 7])
				circle(r=2.5);
			translate([base_length, 9.5])
				circle(r=eta);
			translate([13, 1])
				circle(r=2.5);
			translate([20, 1])
				circle(r=2.5);
		}

		// Actual hole
		translate([15.7, 2.65, lozenge_height + dw])
		mirror([0, 0, 1])
			pinhole(fixed=true);
	}
}

// Rotate a 3vector v = [x,y,z] about the origin by ang degrees
function zr3Vect(v, ang) =
[
	v[0] * cos(ang) - v[1] * sin(ang),
	v[0] * sin(ang) + v[1] * cos(ang),
	v[2]
];


Added stand for small christmas tree

Added stand for small christmas tree

$fs=0.2; // default 2
$fa=3; // default 12

module stand(dia=80) {
    trunk_height=30;
    module trunk() {
        difference() {
            linear_extrude(height=trunk_height, scale=5/10) {
                circle(d=10);
            }
        }
    }

    module legs() {
        module legs_mold() {
            for(i=[0:120:359]) {
                rotate([0,0,i]) translate([-2,0,0]) cube([4,dia/2,15]);
            }
            difference() {
                cylinder(r=dia/2+0.1,h=2);
                translate([0,0,-1]) cylinder(r=dia/2-4,h=4);
            }
        }
        intersection() {
            legs_mold();
            linear_extrude(height=15, scale=0) {
                circle(r=dia/2*1.14);
            }
        }
    }
    difference() {
        union() {
            legs();
            trunk();
        }
        cylinder(d=1.5,h=trunk_height*4,center=true);
    }
}
stand(80);
translate([85,0,0]) stand(80);
translate([42,62,0]) stand(60);

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


fixed issue by introducing tr_xy

fixed issue by introducing tr_xy

learned about children(), will change style of programming

module ring(r=5,d=1) {
	difference() {
		circle(r=r);
		circle(r=r-d);
	}
}
module tr_xy(x,y) {
	if(y==0) {
		for(i=[-1,1])for(j=[-1,1])translate([x*i,x*j])children();
	} else {
		for(i=[-1,1])for(j=[-1,1])translate([x*i,y*j])children();
	}
}

module ring(r=5,d=1) {
	difference() {
		circle(r=r);
		circle(r=r-d);
	}
}
module square_hole(sx=10,sy=0,x=3,y=0,r=1) {
	difference() {
		square([sx,setY(x=sx,y=sy)],center=true);
		for(i=[-1,1])for(j=[-1,1])translate([x*i,y*i]);
	}
}
function setY(x,y) = {
	if(y==0)	return x;
	return y;
}
square_hole(sx=40,sy=10,x=10,r=2.5);*/


main: Use linear_extrusion module for frame

include <thing_libutils/metric-thread.scad>;
include <thing_libutils/metric-hexnut.scad>;
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;

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

include <config.scad>
include <extruder-direct.scad>

xaxis_pos_z = 150*mm;

main();

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

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

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

    // x axis
    translate([0,0,xaxis_pos_z])
    {
        attach([[0,0,0],[0,0,0]],extruder_conn_xcarriage)
            extruder();

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

    // y smooth rods
    for(i=[-1,1])
    translate([i*(yaxis_rod_distance/2),0,0])
    {
        rotate([90,0,0])
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, align=[0,1,0]);
    }

    translate([0,0,yaxis_rod_d])
        cubea(ycarriage_size, align=[0,0,1]);

    // z axis
    for(i=[-1,1])
    translate([i*(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, zaxis_motor_offset_z])
    {
        mirror([i==-1?1:0,0,0])
        {
            zmotor_mount();

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

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

            translate([0,0,xaxis_pos_z-zaxis_motor_offset_z])
                fncylindera(h=zaxis_bearing[2], d=zaxis_bearing[1], align=[0,0,0]);
        }
    }
}

zmotor_mount_motor_offset=5;
zmotor_mount_conn_motor=[[-zmotor_mount_motor_offset, 0, 0],[0,1,0]];

module zmotor_mount()
{
    motor_w = lookup(NemaSideSize,zaxis_motor);

    mount_thickness = 5;
    mount_thickness_h = 8;
    mount_thread_dia = lookup(ThreadSize, extrusion_thread);
    mount_width = motor_w+mount_thickness*2 + mount_thread_dia*8;
    mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;

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

        translate([0, i*((motor_w/2)+mount_thickness/2), 0])
        cubea([mount_thickness, mount_thickness, mount_h], align=[1,0,-1]);
    }

    // top mount plate
    difference()
    {
        translate([-motor_w/2,0,-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size])
                rotate([0,90,0])
                    fncylindera(h=mount_thickness*3,d=mount_thread_dia);
    }

    // bottom mount plate
    difference()
    {
        translate([-motor_w/2,0,-main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size-main_lower_dist_z])
                rotate([0,90,0])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia);
    }

/*#    cubea([motor_w+mount_thickness,motor_w+mount_thickness,zaxis_motor_offset_z], align=[0,0,-1]);*/

    // top plate
    difference()
    {
        cubea([motor_w, motor_w+mount_thickness*2, mount_thickness_h], align=[0,0,1], extrasize=[5,0,0], extrasize_align=[1,0,0]);

        translate([zmotor_mount_motor_offset,0,-1])
        linear_extrude(mount_thickness_h+2)
        stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0])
    linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);

    translate([0, 0, main_height])
    linear_extrusion(h=main_upper_width, align=[0,0,1], orient=[1,0,0]);
}

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

    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    linear_extrusion(h=main_depth, align=[-i,0,-1], orient=[0,1,0]);
}

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

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

include <config.scad>
include <extruder-direct.scad>

xaxis_pos_z = 150*mm;

main();

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

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

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

    // x axis
    translate([0,0,xaxis_pos_z])
    {
        attach([[0,0,0],[0,0,0]],extruder_conn_xcarriage)
            extruder();

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

    // y smooth rods
    for(i=[-1,1])
    translate([i*(yaxis_rod_distance/2),0,0])
    {
        rotate([90,0,0])
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, align=[0,1,0]);
    }

    translate([0,0,yaxis_rod_d])
        cubea(ycarriage_size, align=[0,0,1]);

    // z axis
    for(i=[-1,1])
    translate([i*(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, zaxis_motor_offset_z])
    {
        mirror([i==-1?1:0,0,0])
        {
            zmotor_mount();

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

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

            translate([0,0,xaxis_pos_z-zaxis_motor_offset_z])
                fncylindera(h=zaxis_bearing[2], d=zaxis_bearing[1], align=[0,0,0]);
        }
    }
}

zmotor_mount_motor_offset=5;
zmotor_mount_conn_motor=[[-zmotor_mount_motor_offset, 0, 0],[0,1,0]];

module zmotor_mount()
{
    motor_w = lookup(NemaSideSize,zaxis_motor);

    mount_thickness = 5;
    mount_thickness_h = 8;
    mount_thread_dia = lookup(ThreadSize, extrusion_thread);
    mount_width = motor_w+mount_thickness*2 + mount_thread_dia*8;
    mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;

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

        translate([0, i*((motor_w/2)+mount_thickness/2), 0])
        cubea([mount_thickness, mount_thickness, mount_h], align=[1,0,-1]);
    }

    // top mount plate
    difference()
    {
        translate([-motor_w/2,0,-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size])
                rotate([0,90,0])
                    fncylindera(h=mount_thickness*3,d=mount_thread_dia);
    }

    // bottom mount plate
    difference()
    {
        translate([-motor_w/2,0,-main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size-main_lower_dist_z])
                rotate([0,90,0])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia);
    }

/*#    cubea([motor_w+mount_thickness,motor_w+mount_thickness,zaxis_motor_offset_z], align=[0,0,-1]);*/

    // top plate
    difference()
    {
        cubea([motor_w, motor_w+mount_thickness*2, mount_thickness_h], align=[0,0,1], extrasize=[5,0,0], extrasize_align=[1,0,0]);

        translate([zmotor_mount_motor_offset,0,-1])
        linear_extrude(mount_thickness_h+2)
        stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module extrusion(h, w, l) {
    rotate([90, 0, 90]) {
        translate([2.5, 2.5, 0]) cube([h - 5, w - 5, l]);
        translate([0, 0, 0.1]) cube([h, w, l - 0.2]);
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0])
    rotate([0,0,90])
    cubea([extrusion_size,extrusion_size,main_height], align=[0,i,1]);

    translate([0, 0, main_height])
    cubea([main_upper_width,extrusion_size,extrusion_size], align=[0,0,1]);
}

module gantry_lower()
{
    for(i=[-1,1])
    translate([0,  i*(main_depth/2), 0])
    cubea([main_width,extrusion_size,extrusion_size], align=[0,i,-1]);

    for(i=[-1,1])
    translate([i*(main_width/2), 0])
    rotate([0,0,90])
    cubea([main_depth,extrusion_size,extrusion_size], align=[0,i,-1]);
}


draft

draft

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


Add openSCAD file for the linear camera

Add openSCAD file for the linear camera

//Korrekturfaktoren
// Untermaß Durchmesser kleine Löcher
um_small_hole = -0.4;

// Correction for imperfect printing
// the inner diameter is 49.5 instead of 50.0 after print with PLA_13, so add 0.5 mm
//    (10.01.2016 ad 0.6, because 49.9 was measured)
dadd_inner_tube = 0.6;

dbaseplate = 9.9;
xwidth_base_plate = 90;
zwidth_base_plate = 80;
faces_of_small_holes = 12;
// The top holes lay 20.5 mm above zero
ztop_holes = 20.5;
// The bottom holes lay 17.5 mm below zero
zbottom_holes = -17.5;
// The left holes lay 22.2 mm left of zero in X-Direction
xleft_holes = -22.2;
// The right holes lay 26.8 mm right of zero in X-Direction
xright_holes = 26.8;

// The dimensions of central hole
ztop_central_hole = 13;
zbottom_central_hole = -15;
xleft_central_hole = -30;
xright_central_hole = 17;

// Holes to mount all plates together
// The top holes lay 20.5 mm above zero
ztop_holes_2 = ( zwidth_base_plate / 2 ) - 5;
// The bottom holes lay 17.5 mm below zero
zbottom_holes_2 = - ( zwidth_base_plate / 2 ) + 5;
// The left holes lay 22.2 mm left of zero in X-Direction
xleft_holes_2 = - ( xwidth_base_plate / 2) + 5;
// The right holes lay 26.8 mm right of zero in X-Direction
xright_holes_2 = ( xwidth_base_plate / 2) - 5;

// ------------- Central_plate (To mount the sensor) ------------------

difference(){
// Main Plate for sensor
translate([-xwidth_base_plate/2,0,-zwidth_base_plate/2])
cube([xwidth_base_plate,dbaseplate,zwidth_base_plate],center = false);
// Holes to mount sensor
// bottom left
translate([xleft_holes,dbaseplate,zbottom_holes])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 3.2 - um_small_hole, $fn = faces_of_small_holes );
// bottom right
translate([xright_holes,dbaseplate,zbottom_holes])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 3.2 - um_small_hole, $fn = faces_of_small_holes );
// top left
translate([xleft_holes,dbaseplate,ztop_holes])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 3.2 - um_small_hole, $fn = faces_of_small_holes );
// top right
translate([xright_holes,dbaseplate,ztop_holes])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 3.2 - um_small_hole, $fn = faces_of_small_holes );

// Central hole in main plate for sensor for electronics
translate([xleft_central_hole,0,zbottom_central_hole])
cube([xright_central_hole-xleft_central_hole,dbaseplate,ztop_central_hole-zbottom_central_hole]);

// Holes to fix plates
// bottom left
translate([xleft_holes_2,dbaseplate,zbottom_holes_2])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );
// bottom right
translate([xright_holes_2,dbaseplate,zbottom_holes_2])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );
// top left
translate([xleft_holes_2,dbaseplate,ztop_holes_2])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );
// top right
translate([xright_holes_2,dbaseplate,ztop_holes_2])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );

// Lines for measurements
// left
translate([-xwidth_base_plate/2,dbaseplate,0])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 1, $fn = faces_of_small_holes );
// right
translate([xwidth_base_plate/2,dbaseplate,0])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 1, $fn = faces_of_small_holes );
// top
translate([0,dbaseplate,zwidth_base_plate/2])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 1, $fn = faces_of_small_holes );
// bottom
translate([0,dbaseplate,-zwidth_base_plate/2])
rotate([90,0,0])
cylinder(h=dbaseplate, d = 1, $fn = faces_of_small_holes );
};

// ---------------------- Backplate -------------------------------
// Distance while constructing
yconstruct_backplate = 20;
// Dimensions
dbackplate = 12;
ydepth_screw_head = 4;

// Hole for Cable
ztop_hole_for_cable = 5;
zbottom_hole_for_cable = -9;
xleft_hole_for_cable = 12;
xright_hole_for_cable = xwidth_base_plate/2;
ydeep_for_cable = 1.2;
// Hole2 for Cable
ztop_hole2_for_cable = 5;
zbottom_hole2_for_cable = -9;
xleft_hole2_for_cable = xwidth_base_plate/2-8;
xright_hole2_for_cable = xwidth_base_plate/2;
ydeep2_for_cable = dbackplate;
// Depress Cable
ztop_depress_cable = 12;
zbottom_depress_cable = -14;
xleft_depress_cable = -3;
xright_depress_cable = 11;
yheight_depress_cable = 3;
// Hole for Plug
ztop_hole_plug = 8;
zbottom_hole_plug = -13;
xleft_hole_plug = -28;
xright_hole_plug = -13;
ydeep_plug = 9;

translate([0,dbaseplate + yconstruct_backplate,0])
union(){
difference(){
// Back Plate for sensor
translate([-xwidth_base_plate/2,0,-zwidth_base_plate/2])
cube([xwidth_base_plate,dbackplate,zwidth_base_plate],center = false);

// Holes to fix plates
// bottom left
translate([xleft_holes_2,dbackplate,zbottom_holes_2])
rotate([90,0,0])
cylinder(h=dbackplate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );
// bottom right
translate([xright_holes_2,dbackplate,zbottom_holes_2])
rotate([90,0,0])
cylinder(h=dbackplate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );
// top left
translate([xleft_holes_2,dbackplate,ztop_holes_2])
rotate([90,0,0])
cylinder(h=dbackplate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );
// top right
translate([xright_holes_2,dbackplate,ztop_holes_2])
rotate([90,0,0])
cylinder(h=dbackplate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );

// Lines for measurements
// left
translate([-xwidth_base_plate/2,dbackplate,0])
rotate([90,0,0])
cylinder(h=dbackplate, d = 1, $fn = faces_of_small_holes );
// right
translate([xwidth_base_plate/2,dbackplate,0])
rotate([90,0,0])
cylinder(h=dbackplate, d = 1, $fn = faces_of_small_holes );
// top
translate([0,dbackplate,zwidth_base_plate/2])
rotate([90,0,0])
cylinder(h=dbackplate, d = 1, $fn = faces_of_small_holes );
// bottom
translate([0,dbackplate,-zwidth_base_plate/2])
rotate([90,0,0])
cylinder(h=dbackplate, d = 1, $fn = faces_of_small_holes );

// Holes for screw heads to mount sensor
// bottom left
translate([xleft_holes,ydepth_screw_head,zbottom_holes])
rotate([90,0,0])
cylinder(h=ydepth_screw_head, d = 8 - um_small_hole, $fn = faces_of_small_holes );
// bottom right
translate([xright_holes,ydepth_screw_head,zbottom_holes])
rotate([90,0,0])
cylinder(h=ydepth_screw_head, d = 8 - um_small_hole, $fn = faces_of_small_holes );
// top left
translate([xleft_holes,ydepth_screw_head,ztop_holes])
rotate([90,0,0])
cylinder(h=ydepth_screw_head, d = 8 - um_small_hole, $fn = faces_of_small_holes );
// top right
translate([xright_holes,ydepth_screw_head,ztop_holes])
rotate([90,0,0])
cylinder(h=ydepth_screw_head, d = 8 - um_small_hole, $fn = faces_of_small_holes );

// Hole for Plug in backplate
translate([xleft_hole_plug,0,zbottom_hole_plug])
cube([xright_hole_plug-xleft_hole_plug,ydeep_plug,ztop_hole_plug-zbottom_hole_plug]);
// Hole for Cable in backplate
translate([xleft_hole_for_cable,0,zbottom_hole_for_cable])
cube([xright_hole_for_cable-xleft_hole_for_cable,ydeep_for_cable,ztop_hole_for_cable-zbottom_hole_for_cable]);
// Hole2 for Cable in backplate
translate([xleft_hole2_for_cable,0,zbottom_hole2_for_cable])
cube([xright_hole2_for_cable-xleft_hole2_for_cable,ydeep2_for_cable,ztop_hole2_for_cable-zbottom_hole2_for_cable]);
};
// Depress Cable
translate([xleft_depress_cable,-yheight_depress_cable,zbottom_depress_cable])
cube([xright_depress_cable-xleft_depress_cable,yheight_depress_cable,ztop_depress_cable-zbottom_depress_cable]);
};

// ------------------------ Front of camera ------------------------------

// Distance while constructing
yconstruct_front = 0;
// Dimensions
dfront_plate = 12;

// Front Plate is wider
front_plate_wider = 20;
xwidth_front_plate = xwidth_base_plate + front_plate_wider;
zwidth_front_plate = zwidth_base_plate + front_plate_wider;

// Empty Space in Middle

ztop_hole_front = zwidth_base_plate/2 - 10;
zbottom_hole_front = -zwidth_base_plate/2 +10;
xleft_hole_front = -xwidth_base_plate/2 +10 ;
xright_hole_front = xwidth_base_plate/2 -10;

// Shielding
shield_height = 20;

translate([0,- dfront_plate + yconstruct_front,0])
union(){
// Cube at bottom so that camera does not drop
translate([-5,-110,-50])
cube([10,110,10]);
// Shielding over sensor and backplate
difference(){
 translate([-xwidth_front_plate/2,dfront_plate,-zwidth_front_plate/2])
cube([xwidth_front_plate,shield_height,zwidth_front_plate],center = false);
 translate([-xwidth_base_plate/2,dfront_plate,-zwidth_base_plate/2])
cube([xwidth_base_plate,shield_height,zwidth_base_plate],center = false);

// Lines for measurements at shielding
// left
translate([-xwidth_front_plate/2,shield_height+dfront_plate,0])
rotate([90,0,0])
cylinder(h=shield_height, d = 1, $fn = faces_of_small_holes );
// right
translate([xwidth_front_plate/2,shield_height+dfront_plate,0])
rotate([90,0,0])
cylinder(h=shield_height, d = 1, $fn = faces_of_small_holes );
// top
translate([0,shield_height+dfront_plate,zwidth_front_plate/2])
rotate([90,0,0])
cylinder(h=shield_height, d = 1, $fn = faces_of_small_holes );
// bottom
translate([0,shield_height+dfront_plate,-zwidth_front_plate/2])
rotate([90,0,0])
cylinder(h=shield_height, d = 1, $fn = faces_of_small_holes );

};
difference(){
// Front lower plate
translate([-xwidth_front_plate/2,0,-zwidth_front_plate/2])
cube([xwidth_front_plate,dfront_plate,zwidth_front_plate],center = false);

// Holes to fix plates
// bottom left
translate([xleft_holes_2,dfront_plate,zbottom_holes_2])
rotate([90,0,0])
cylinder(h=dfront_plate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );
// bottom right
translate([xright_holes_2,dfront_plate,zbottom_holes_2])
rotate([90,0,0])
cylinder(h=dfront_plate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );
// top left
translate([xleft_holes_2,dfront_plate,ztop_holes_2])
rotate([90,0,0])
cylinder(h=dfront_plate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );
// top right
translate([xright_holes_2,dfront_plate,ztop_holes_2])
rotate([90,0,0])
cylinder(h=dfront_plate, d = 4.2 - um_small_hole, $fn = faces_of_small_holes );

// Lines for measurements
// left
translate([-xwidth_front_plate/2,dfront_plate,0])
rotate([90,0,0])
cylinder(h=dfront_plate, d = 1, $fn = faces_of_small_holes );
// right
translate([xwidth_front_plate/2,dfront_plate,0])
rotate([90,0,0])
cylinder(h=dfront_plate, d = 1, $fn = faces_of_small_holes );
// top
translate([0,dfront_plate,zwidth_front_plate/2])
rotate([90,0,0])
cylinder(h=dfront_plate, d = 1, $fn = faces_of_small_holes );
// bottom
translate([0,dfront_plate,-zwidth_front_plate/2])
rotate([90,0,0])
cylinder(h=dfront_plate, d = 1, $fn = faces_of_small_holes );

// Empty Space in Middle

translate([xleft_hole_front,0,zbottom_hole_front])
cube([xright_hole_front-xleft_hole_front,dfront_plate,ztop_hole_front-zbottom_hole_front]);

};
// Tube at the front
ht1 = 5;
da1 = 99;
dt1 = 15;
ht2 = 5;
da2 = 95;
dt2 = 15;
ht3 = 5;
da3 = 90;
dt3 = 15;
ht4 = 5;
da4 = 85;
dt4 = 15;
ht5 = 5;
da5 = 80;
dt5 = 15;
ht6 = 5;
da6 = 75;
dt6 = 15;
ht7 = 5;
da7 = 70;
dt7 = 15;
ht8 = 5;
da8 = 65;
dt8 = 15;
faces_of_tube = 80;
translate([0,0,0])
rotate([90,0,0])
difference(){
  cylinder(h=ht1, d = da1, $fn = faces_of_tube);
  cylinder(h=ht1, d = da1-dt1, $fn = faces_of_tube);
};

translate([0,-ht1,0])
rotate([90,0,0])
difference(){
  cylinder(h=ht2, d = da2, $fn = faces_of_tube);
  cylinder(h=ht2, d = da2-dt2, $fn = faces_of_tube);
};

translate([0,-ht1 -ht2,0])
rotate([90,0,0])
difference(){
  cylinder(h=ht3, d = da3, $fn = faces_of_tube);
  cylinder(h=ht3, d = da3-dt3, $fn = faces_of_tube);
};

translate([0,-ht1 -ht2 -ht3,0])
rotate([90,0,0])
difference(){
  cylinder(h=ht4, d = da4, $fn = faces_of_tube);
  cylinder(h=ht4, d = da4-dt4, $fn = faces_of_tube);
};

translate([0,-ht1 -ht2 -ht3 -ht4,0])
rotate([90,0,0])
difference(){
  cylinder(h=ht5, d = da5, $fn = faces_of_tube);
  cylinder(h=ht5, d = da5-dt5, $fn = faces_of_tube);
};

translate([0,-ht1 -ht2 -ht3 -ht4 -ht5,0])
rotate([90,0,0])
difference(){
  cylinder(h=ht6, d = da6, $fn = faces_of_tube);
  cylinder(h=ht6, d = da6-dt6, $fn = faces_of_tube);
};

translate([0,-ht1 -ht2 -ht3 -ht4 -ht5 -ht6,0])
rotate([90,0,0])
difference(){
  cylinder(h=ht7, d = da7, $fn = faces_of_tube);
  cylinder(h=ht7, d = da7-dt7, $fn = faces_of_tube);
};

translate([0,-ht1 -ht2 -ht3 -ht4 -ht5 -ht6 -ht7,0])
rotate([90,0,0])
difference(){
  cylinder(h=ht8, d = da8, $fn = faces_of_tube);
  cylinder(h=ht8, d = da8-dt8, $fn = faces_of_tube);
};

translate([0,-40,0])
rotate([90,0,0])
difference(){
  cylinder(h=100, d = 60, $fn = faces_of_tube);
  cylinder(h=100, d = 50, $fn = faces_of_tube);
};

};

// ------------------------ Lense holder ------------------------------

// Distance while constructing
// -50 ganz eingeschoben
// -80 ca unendlich fokussiert
// -120 ca Fokus 1 Meter eingestellt
ylense_holder = -120;
xlense_holder = -100;
ylength_of_main_tube = 110;
dmain_tube_outer = 70;
dmain_tube_inner = 60 + dadd_inner_tube;
// Do not adjust a radius used for outside with correction
// value for inner tube:
dmain_tube_inner_outside = 60;

// Diameter for Lense
dlense = 51.2;

// Correct Positions of Mutter
dMutter_lense = dlense -50 + dadd_inner_tube -0.7;
dMutter_tube = dadd_inner_tube -0.2;
faces_of_tube_lense_holder = 80;
translate([xlense_holder,ylense_holder,0])
difference(){
union(){

// Make tube thicker for screw
translate([26.9,-125,0])
rotate([0,90,0])
translate([0,0,4])
linear_extrude(height = 8, center = true)
circle(d=15,$fn=40);

// Make tube thicker for screw
translate([-26.9,-125,0])
rotate([0,-90,0])
translate([0,0,4])
linear_extrude(height = 8, center = true)
circle(d=15,$fn=40);

// Make tube thicker for screw
translate([26.9,-20,0])
rotate([0,90,0])
translate([0,0,9])
linear_extrude(height = 8, center = true)
circle(d=15,$fn=40);

// Make tube thicker for screw
translate([-26.9,-20,0])
rotate([0,-90,0])
translate([0,0,9])
linear_extrude(height = 8, center = true)
circle(d=15,$fn=40);

// Main Tube
rotate([90,0,0])
difference(){
  cylinder(h=ylength_of_main_tube, d = dmain_tube_outer, $fn = faces_of_tube_lense_holder);
  cylinder(h=ylength_of_main_tube, d = dmain_tube_inner, $fn = faces_of_tube_lense_holder);
};
// Base for Lense
translate([0,-ylength_of_main_tube+10,0])
rotate([90,0,0])
difference(){
  cylinder(h=10, d = dmain_tube_inner, $fn = faces_of_tube_lense_holder);
  cylinder(h=10, d = 45, $fn = faces_of_tube_lense_holder);
};
// Ring to guide lense and to mount further structures
translate([0,-ylength_of_main_tube,0])
rotate([90,0,0])
difference(){
  cylinder(h=40, d = dmain_tube_inner_outside, $fn = faces_of_tube_lense_holder);
  cylinder(h=40, d = dlense + dadd_inner_tube, $fn = faces_of_tube_lense_holder);
};
// Structure to mount further devices

// Cube at bottom so that camera does not drop
translate([-5,-120,-50])
cube([10,45,10]);
// Fix Cube to tube
translate([-5,-120,-40])
cube([10,10,11]);
translate([-5,-85,-40])
cube([10,10,8]);

// Mutter positive

};

// Mutter negative

// Place for "Mutter"
translate([26.9 + dMutter_lense ,-125,0])
rotate([0,90,0])
union(){
linear_extrude(height = 4.8, center = true)
circle(d=9.2,$fn=6);
translate([0,0,8])
linear_extrude(height = 15, center = true)
circle(d=5.2,$fn=40);
};

// Place for "Mutter"
translate([-26.9 - dMutter_lense,-125,0])
rotate([0,-90,0])
union(){
linear_extrude(height = 4.8, center = true)
circle(d=9.2,$fn=6);
translate([0,0,8])
linear_extrude(height = 15, center = true)
circle(d=5.2,$fn=40);
};

// 2.

// Place for "Mutter"
translate([31.9 + dMutter_tube,-20,0])
rotate([0,90,0])
union(){
linear_extrude(height = 4.8, center = true)
circle(d=9.2,$fn=6);
translate([0,0,8])
linear_extrude(height = 15, center = true)
circle(d=5.2,$fn=40);
};

// Place for "Mutter"
translate([-31.9 -dMutter_tube,-20,0])
rotate([0,-90,0])
union(){
linear_extrude(height = 4.8, center = true)
circle(d=9.2,$fn=6);
translate([0,0,8])
linear_extrude(height = 15, center = true)
circle(d=5.2,$fn=40);
};

};

// ------------------------ Ring to fix lense ------------------------------
xfix_lense = -20;
translate([xlense_holder+xfix_lense,ylense_holder,0])
union(){
 translate([0,-ylength_of_main_tube-10,0])
rotate([90,0,0])
difference(){
  cylinder(h=10, d = dlense, $fn = faces_of_tube_lense_holder);
  cylinder(h=10, d = 45, $fn = faces_of_tube_lense_holder);
};
};

//translate([0,-52,0])
//cube([100,1,100]);

//translate([0,-152,0])
//cube([100,1,100]);

error: pathspec 'Case/LinearCamera1_V1.1.scad' did not match any file(s) known to git


Updated milwaukee battery socket

Updated milwaukee battery socket

use <BezierScad.scad>;

// dimension
// heights:
// - base = 0mm
// - slope highest point = 26.5mm
// - slope mid point = 14mm
// - hook lowest edge = 19mm

module outer_horizontal_boundary(dim, x0, y0, x1, y1, y2) {
    module half() {
        BezLine([
          [0, 0],
          [dim*y0, dim*x0],
          [dim*y1, dim*x1],
          [dim*y2, dim],
          [0, dim],
          ], width = [0.1, 0.1], resolution = 6);
    }
    half();
    mirror([1,0,0]) half();
}

/*
#color("green") difference() {
translate([0,-19.5, 3]) hull() linear_extrude(height=10) outer_horizontal_boundary(52, 0.06, 0.72, 0.66, 0.41, 0.30);
  translate([0,0.5,0]) battery_tower2();
}
*/

/*
#color("green") difference() {
      translate([0,-19.5, -55]) hull() linear_extrude(height=10)    outer_horizontal_boundary(52, 0.04, 0.68, 0.66, 0.45, 0.30);
  translate([0,0.5,0]) battery_tower();
}//*/

//translate([0,-15,-16]) hull() outer_horizontal_boundary(46.4, 0.9, 0.58, 0.37, 0.26);
module outline(height=10, type=1) {
  translate([0,-20.5, -height/2]) hull() linear_extrude(height=height) {
    if (type == 1) {
      outer_horizontal_boundary(52, 0.04, 0.68, 0.66, 0.45, 0.30);
    } else if (type == 2) {
      outer_horizontal_boundary(52, 0.04, 0.73, 0.81, 0.43, 0.2);
    } else if (type == 3) {
      outer_horizontal_boundary(52, 0.03, 0.73, 0.86, 0.44, 0.2);
    }
  }
}

module thin_wall() {
  type = 2;
  intersection() {
//*
  minkowski() {
    difference() {
      cube([100,100,100], true);
      outline(110,type);
    }
    sphere(r=1);
  }
//    */
    outline(110,type);
  }
}
//translate([0,0,40])#outline(1,3);
module hooks2() {
  module hook() {
    radius=40;
    intersection() {
      translate([0,radius,0]) {
        translate([0,0,19]) cylinder(r=radius+1.5,h=4,$fn=120);
        cylinder(r=radius,h=20,$fn=120);
      };
      cube([10,10,50],true);
    }
    intersection() {
      translate([0,radius,0]) {
        cylinder(r=radius-0.5,h=23,$fn=120);
      };
      translate([2,0,0]) cube([14,10,50],true);
    }
  }

  for(a=[0:1:1]) {
    mirror([a,0,0]) translate([17.5,13.5,0]) color("green")rotate([0,0,112]) hook();
  }

}

module hooks() {
  module hook() {
    radius=40;
    intersection() {
      union() {
        translate([0,radius,0]) {
          translate([0,0,19]) cylinder(r=radius+2,h=4,$fn=120);
          cylinder(r=radius,h=20,$fn=120);
          translate([0,0,2]) rotate([-4,0,0]) translate([0,-1,-5]) cylinder(r=radius,h=20,$fn=120);
        };
      }
      rotate([0,0,-30])cube([10,10,50],true);
    }
    intersection() {
      translate([0,radius,0]) {
        cylinder(r=radius-0.5,h=23,$fn=120);
      };
      translate([2,0,0]) cube([14,10,50],true);
    }
  }

  for(a=[0:1:1]) {
    mirror([a,0,0]) translate([17.5,13.5,0]) color("green")rotate([0,0,112]) hook();
  }

}

//translate([20,-5,60]) cube([1,29,1],true);
%translate([50,-20,26.5]) rotate([-19,0,0]) translate([0,0,0.5])color("gray") cube([1,100,1],true);
%translate([50,22,0]) rotate([-65,0,0]) translate([0,0,0.5])color("gray") cube([1,100,1],true);

module mold() {
  hull()
  {
  translate([0,13.13,11.91]) rotate([0,90,0]) cylinder(d=6,h=100,center=true,$fn=36);
//  translate([0,11,10.1]) rotate([0,90,0]) cylinder(d=10,h=100,center=true,$fn=36);
  translate([0,-20,26.5])rotate([-19,0,0])translate([0,0,-20])cube([100,2,40],true);
  translate([0,22,0])rotate([-65,0,0])translate([0,0,-1])cube([100,20,2],true);
  }
}
//color("red")mold();
module handle() {
  hull() {
  translate([0,0,1]) outline(2,2);
  translate([0,0,29]) outline(22,3);
  }
}
difference() {
  union() {
//    intersection() {
//      thin_wall();
//      translate([0,0,15]) cube([1000,1000,30], true);
//    }
    color("blue")difference() {
//      translate([0,0,26+5]) outline(16,2);
      handle();
      translate([0,0,-0.01]) battery_tower();
    }
  }
  mold();
  hooks();
}
//battery_tower();

//translate([0,0,50]) hooks();

//translate([0,0,120])color("green")cube([46,1,1],true);
//translate([0,-18, 50]) hull() outer_horizontal_boundary(50, 0.83, 0.62, 0.37, 0.26);

module battery_tower() {
    clearance = 0.0;
    battery_r = 11 + clearance;
    battery_distance = 9.4;
    cell_h = 60;
    big_tower_h = cell_h + 10;
    battery_d = battery_r * 2;
    big_tower_w = battery_d * 1.1;
    triangle_h = battery_distance * sqrt(3);
    big_tower_offset = triangle_h - battery_r;

    module trunk(height) {
        hull() {
            translate([-battery_distance, 0, 0])
                cylinder(height, r=battery_r,$fn=60);
            translate([battery_distance, 0, 0])
                cylinder(height, r=battery_r,$fn=60);
            translate([0, triangle_h, 0])
                cylinder(height, r=battery_r+0.0,$fn=60);
        }
    }

    trunk(cell_h);

    module edge(height) {
      hull() {
      translate([12.8,21.5])cylinder(d=1.5+ clearance*2,h=height, $fn=36);
      translate([12.8,19.4])cylinder(d=1.5+ clearance*2,h=height, $fn=36);
      translate([10,19.2])cylinder(d=4+ clearance*2,h=height, $fn=36);
      }
    }
    color("red") edge(big_tower_h);
    color("red") mirror([1,0,0]) edge(big_tower_h);
    intersection() {
        trunk(big_tower_h);
        translate([-big_tower_w / 2, big_tower_offset, 0])
            cube([big_tower_w, big_tower_w, big_tower_h]);
    }

    color("blue") translate([6.5, 15, big_tower_h]) cube([0.2, 7, 10], center = true);
    color("blue") translate([-6.5, 15, big_tower_h]) cube([0.2, 7, 10], center = true);
}

use <BezierScad.scad>;

// dimension
// heights:
// - base = 0mm
// - slope highest point = 26.5mm
// - slope mid point = 14mm
// - hook lowest edge = 19mm

module outer_horizontal_boundary(dim, x0, y0, x1, y1, y2) {
    module half() {
        BezLine([
          [0, 0],
          [dim*y0, dim*x0],
          [dim*y1, dim*x1],
          [dim*y2, dim],
          [0, dim],
          ], width = [0.1, 0.1], resolution = 6);
    }
    half();
    mirror([1,0,0]) half();
}

/*
#color("green") difference() {
translate([0,-19.5, 3]) hull() linear_extrude(height=10) outer_horizontal_boundary(52, 0.06, 0.72, 0.66, 0.41, 0.30);
  translate([0,0.5,0]) battery_tower2();
}
*/

/*
#color("green") difference() {
      translate([0,-19.5, -55]) hull() linear_extrude(height=10)    outer_horizontal_boundary(52, 0.04, 0.68, 0.66, 0.45, 0.30);
  translate([0,0.5,0]) battery_tower();
}//*/

//translate([0,-15,-16]) hull() outer_horizontal_boundary(46.4, 0.9, 0.58, 0.37, 0.26);
module outline(height=10, type=1) {
  translate([0,-19.5, -height/2]) hull() linear_extrude(height=height) {
    if (type == 1) {
      outer_horizontal_boundary(52, 0.04, 0.68, 0.66, 0.45, 0.30);
    } else if (type == 2) {
      outer_horizontal_boundary(52, 0.04, 0.73, 0.81, 0.43, 0.2);
    }
  }
}

module thin_wall() {
  type = 2;
  intersection() {
//*
  minkowski() {
    difference() {
      cube([100,100,100], true);
      outline(110,type);
    }
    sphere(r=1);
  }
//    */
    outline(110,type);
  }
}

module hook() {
  radius=40;
  intersection() {
    translate([0,radius,0]) {
      translate([0,0,19]) cylinder(r=radius+1.5,h=4,$fn=120);
      cylinder(r=radius,h=20,$fn=120);
    };
    cube([10,10,50],true);
  }
  intersection() {
    translate([0,radius,0]) {
      cylinder(r=radius-0.5,h=23,$fn=120);
    };
    translate([2,0,0]) cube([14,10,50],true);
  }
}
module hooks() {
  for(a=[0:1:1]) {
    mirror([a,0,0]) translate([17.5,14,0]) color("green")rotate([0,0,112]) hook();
  }

}
//translate([20,-5,60]) cube([1,29,1],true);
%translate([50,-19.5,26.5]) rotate([-19,0,0]) translate([0,0,0.5])color("gray") cube([1,100,1],true);
%translate([50,22.5,0]) rotate([-65,0,0]) translate([0,0,0.5])color("gray") cube([1,100,1],true);

module mold() {
  hull()
  {
  translate([0,13.63,11.91]) rotate([0,90,0]) cylinder(d=6,h=100,center=true,$fn=36);
//  translate([0,11,10.1]) rotate([0,90,0]) cylinder(d=10,h=100,center=true,$fn=36);
  translate([0,-19.5,26.5])rotate([-19,0,0])translate([0,0,-20])cube([100,2,40],true);
  translate([0,22.5,0])rotate([-65,0,0])translate([0,0,-1])cube([100,20,2],true);
  }
}
//color("red")mold();
difference() {
  union() {
//    intersection() {
//      thin_wall();
//      translate([0,0,15]) cube([1000,1000,30], true);
//    }
    color("blue")difference() {
//      translate([0,0,26+5]) outline(16,2);
      translate([0,0,20]) outline(40,2);
      translate([0,0.5,-0.01]) battery_tower();
    }
  }
  mold();
  hooks();
}
//battery_tower();

//translate([0,0,120])color("green")cube([46,1,1],true);
//translate([0,-18, 50]) hull() outer_horizontal_boundary(50, 0.83, 0.62, 0.37, 0.26);

module battery_tower() {
    clearance = 0.0;
    battery_r = 11 + clearance;
    battery_distance = 9.4;
    cell_h = 60;
    big_tower_h = cell_h + 10;
    battery_d = battery_r * 2;
    big_tower_w = battery_d * 1.1;
    triangle_h = battery_distance * sqrt(3);
    big_tower_offset = triangle_h - battery_r;

    module trunk(height) {
        hull() {
            translate([-battery_distance, 0, 0])
                cylinder(height, r=battery_r,$fn=60);
            translate([battery_distance, 0, 0])
                cylinder(height, r=battery_r,$fn=60);
            translate([0, triangle_h, 0])
                cylinder(height, r=battery_r+0.0,$fn=60);
        }
    }

    trunk(cell_h);

    module edge(height) {
      hull() {
      translate([12.8,21.5])cylinder(d=1.5+ clearance*2,h=height, $fn=36);
      translate([12.8,19.4])cylinder(d=1.5+ clearance*2,h=height, $fn=36);
      translate([10,19.2])cylinder(d=4+ clearance*2,h=height, $fn=36);
      }
    }
    color("red") edge(big_tower_h);
    color("red") mirror([1,0,0]) edge(big_tower_h);
    intersection() {
        trunk(big_tower_h);
        translate([-big_tower_w / 2, big_tower_offset, 0])
            cube([big_tower_w, big_tower_w, big_tower_h]);
    }

    color("blue") translate([6.5, 15, big_tower_h]) cube([0.2, 7, 10], center = true);
    color("blue") translate([-6.5, 15, big_tower_h]) cube([0.2, 7, 10], center = true);
}