removed some debugging pieces

removed some debugging pieces

use <StepMotor_28BYJ-48.scad>;
use <Hub_28BYJ-48.scad>;
include <Bearing_6807-2RS.scad>;

// global rendering parameters
$fn = 64; // production
//$fn = 48; // development
//$fn = 24; // LQ
echo($fn);

// library examples
// translate([100, 100, 10]) { StepMotor28BYJ(); }
// stepperHub(10, 7, 6, 3.1, 1.5, 2.75);
//translate([0, 0, 8]) bearing6807_2RS();
// bearingInnerStep(bearing6807_2RS_d - iFitAdjust, 2, 2);
//shoulderBase(2, 55, 9.1, 3.1);

// interference fit adjustment for 3D printer
iFitAdjust = .4;

// shoulder base parameters
shoulderBaseHeight = 3;
shoulderBaseDiameter = 55;
shaftBossDiameter = 10;
mountScrewDiameter = 3.1;
bearingStep = 2; // size in mm of bearing interface step
// joint parameters
hubHeight = 10;
hubRadius = 7;
shaftHeight = 6;
shaftRadius = 3.1;
setScrewRadius = 1.5;
setScrewHeight = 2.75;
spokeWidth = 3;
spokes = 6;
screwTabs = 4;
screwTabHeight = 4;
armLength = 100;
// misc
baseDeckExtension = 60;
boundingBox = 8;
boundingBoxHalf = boundingBox / 2;
// 8 is distance from shaft center to screw center on x axis
// 35 is screw center to screw center on y axis
shaftCenterToMountHoldCenterXAxis = 8;
mountHoleCenterToMountHoleCenter = 35;
leadScrewDiameter = 8;
// forearm
forearmLength = 75;

/* Pieces in this model
** Shoulder:
*** Base plate
*** Top plate
*** Lower arm
*** Upper arm
** Forearm:
*** ?
** Hand:
*** ?
*/

// SHOULDER
// shoulder base
module shoulderBasePlate() { // make me
color([.7, .7, 1])
    shoulderBase(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
}
shoulderBasePlate();
// shoulder lower stepper
rotate([0, 180, 0])
    translate([-8, 0, 10])
        StepMotor28BYJ();
// lower shoulder bearing
translate([0, 0, shoulderBaseHeight + bearingStep])
    %bearing6807_2RS();
// shoulder top
color([.6, .6, .9])
    translate([0, 0, 2 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep)])
    rotate([180, 0, 0])
        shoulderBase(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// upper shoulder bearing
translate([0, 0, shoulderBaseHeight + (3 * bearing6807_2RS_B) + (7 * bearingStep)])
    %bearing6807_2RS();
// shoulder upper stepper
rotate([0, 0, 180])
    translate([-8, 0, 10 + 2 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep)])
        StepMotor28BYJ();
// shoulder spacers
module shoulderSpacerSet() { // make me
color([.7, .6, .2])
shoulderSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
color([.7, .6, .2])
translate([baseDeckExtension / 3, 0, 0])
shoulderSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
}
shoulderSpacerSet();
// end shoulder

// lower arm including the shoulder - arm joint
//render()
module armSection() { // make me
color([1, .7, .7])
    translate([0, 0, shoulderBaseHeight + bearing6807_2RS_B])
        armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
}
armSection();
// upper arm
//render()
color([.9, .7, .7])
    translate([0, 0, shoulderBaseHeight + ( 2*bearing6807_2RS_B) + (12 * bearingStep) - (.5 * bearingStep)])
        rotate([180, 0, 0])
            armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
// elbow joint pieces
// lower bearing
translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + bearingStep])
    %bearing6807_2RS();
// arm upper stepper
translate([-armLength + 8, 0, shoulderBaseHeight + ( 3*bearing6807_2RS_B) + (16 * bearingStep) - (.5 * bearingStep)])
    rotate([0, 0, 180])
        StepMotor28BYJ();
// arm lower stepper
rotate([0, 180, 0])
    translate([armLength - 8, 0, bearingStep * 2])
        StepMotor28BYJ();
// arm spacers
module armSpacerSet() { // make me
color([.6, .6, .3])
    armSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
}
armSpacerSet();
// end arm

// forearm pieces
// lower
module forearmSection() { // make me
color([.1, .7, .1])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
//translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (14 *bearingStep)])
    forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
}
forearmSection();
// upper
//render()
color([.2, .8, .2])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
    rotate([180, 0, 0])
        forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
// forearm upper bearing
translate([-armLength, 0, shoulderBaseHeight + (2 * bearing6807_2RS_B) + (7 * bearingStep)])
    %bearing6807_2RS();
// forearm spacers
// none at this time

//bearingInnerStep(bearing6807_2RS_d - iFitAdjust, 2, 2);
module bearingInnerStep(bearingID, stepHeight, stepWidth) {
    difference() {
        union() {
            // this fits inside of the bearing
            cylinder(h = stepHeight * 2, d = bearingID);
            // this rests on the bearing inner lip
            cylinder(h = stepHeight, d = bearingID + stepWidth);
        }
        // remove center
        cylinder(h = stepHeight * 2, d = bearingID - (stepWidth * 2));
    }
}

//translate([0, 0, 12]) bearingOuterStep(bearing6807_2RS_D + iFitAdjust, 2, 2);
module bearingOuterStep(bearingOD, stepHeight, stepWidth) {
    //render(convexivity = 3)
    difference() {
        cylinder(h = stepHeight * 2, d = bearingOD + stepWidth);
        cylinder(h = stepHeight * 2, d = bearingOD - stepWidth);
        cylinder(h = stepHeight, d = bearingOD);
    }
}

module shoulderSpacers(bearingOD, screwSpacerHeight) {
    union() {
        // screw holes for joining to arm
        rotate([0, 0, -30])
        radial_array_partial(vec = [0, 0, 1], n = 6, 2)
            translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 1.0])
        difference() {
            union () {
                cylinder(h = screwSpacerHeight, r = setScrewRadius * 2);

                }
            cylinder(h = screwTabHeight, r = setScrewRadius);
        }
    }
}

module armSpacers(bearingOD, screwSpacerHeight) {
    union() {
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = 4)
            translate([bearingOD / 2 + (setScrewRadius * 2), 0, shoulderBaseHeight + bearing6807_2RS_B + 2 * bearingStep])
        difference() {
            union () {
                cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius * 2);

                }
            cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius);
        }
        // TODO: put in spacers along arm, make sure holes exist in arm
        translate([- armLength, 0, 0])
        rotate([0, 0, -30])
        radial_array_partial(vec = [0, 0, 1], n = 6, 2)
            translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight + bearing6807_2RS_B + 2 * bearingStep])
        difference() {
            union () {
                cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius * 2);

                }
            cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius);
        }
    }
}

// armJointSpacer(bearing6807_2RS_D - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
module armJointSpacer(bearingID, bearingOD, bearingStep, shaftBossDiameter, mountScrewDiameter) {
    union() {
        difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
            cylinder(h = bearingStep * 2, d = bearingID);
        }
        translate([0, 0, bearingStep * 2])
                bearingInnerStep(bearingID, bearingStep, bearingStep);
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * bearingStep) - screwTabHeight])
                    difference() {
                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }
                        cylinder(h = screwTabHeight, r = setScrewRadius);
                    }
    }
}

//shoulderBase(2, 55, 9.1, 3.1);
// WARNING: has some hard-coded non-parametric values in here!
module shoulderBase(bearingID, bearingOD, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter) {
    mountHoleDepth = shoulderBaseHeight;

    //render(convexivity = 3)
    difference() {
        union () {
            cylinder(h = shoulderBaseHeight, d = shoulderBaseDiameter);
            translate([0, 0, shoulderBaseHeight])
                bearingInnerStep(bearing6807_2RS_d - iFitAdjust, bearingStep, bearingStep);
            // 40 is the length of deck extension from the baseplate in x
            translate([0, -shoulderBaseDiameter / 2, 0])
                cube([baseDeckExtension, shoulderBaseDiameter, shoulderBaseHeight], center = false);
        }
        // motor shaft hole
        cylinder(h = shoulderBaseHeight + (bearingStep * 2), d = shaftBossDiameter);
        // mounting holes

        translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        // lead screw hole
        translate([baseDeckExtension - (leadScrewDiameter * 1.5), 0, 0])
            cylinder(h = shoulderBaseHeight, d = leadScrewDiameter + (leadScrewDiameter / 2));
        // upper to lower spacer screw holes
        rotate([0, 0, -30])
            radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 0])
                    cylinder(h = screwTabHeight, r = setScrewRadius);
           translate([baseDeckExtension / 3, 0, 0])
            rotate([0, 0, -30])
            radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 0])
                    cylinder(h = screwTabHeight, r = setScrewRadius);
    }
    // NOTE: need to add LM8UU mounts
}

module armLower(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength) {
    armWidth = bearingOD / 2;
    //render(convexivity = 3)
    difference() {
    union() {
        armInnerJoint(bearingOD, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight);
        translate([-armLength, 0, 0])
            armOuterJointBase(bearingOD, bearingStep, setScrewRadius, screwTabs, screwTabHeight);
        difference() {
            translate([-armLength, -armWidth / 2, 0])
                cube([armLength, armWidth, bearingStep * 2], center=false);
            cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-armLength, 0, 0])
                cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                cube([armLength - bearingOD - (boundingBox + boundingBoxHalf), armWidth - boundingBox, bearingStep * 2], center = false);
        }
        difference() {
            intersection() {

                translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([armLength - bearingOD - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
                for (i = [ bearingOD / 2 - boundingBoxHalf: armWidth : armLength]) {
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, 45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, -45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                }
            }

        }
               difference() {
               hull() {
                   translate([- armLength, 0, bearingStep])
                    linear_extrude(height = 2 * bearingStep, center = true, twist = 0)
                        polygon(points=[[0, -bearingOD/2 - setScrewRadius/2], [bearingOD / 2 + (setScrewRadius * 8), -armWidth / 2], [bearingOD / 2 + (setScrewRadius * 8), armWidth / 2], [0, bearingOD/2 + setScrewRadius/2]]);
                translate([- armLength, 0, 0])
                    rotate([0, 0, -30])
                    radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                        translate([bearingOD / 2 + (setScrewRadius * 8), 0, 0])
                            cylinder(h = 2 * bearingStep, r = setScrewRadius * 2);

                    }
                translate([- armLength, 0, 0])
                    rotate([0, 0, -30])
                    radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                        translate([bearingOD / 2 + (setScrewRadius * 8), 0, 0])
                        cylinder(h = 2 * bearingStep, r = setScrewRadius);

                 translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([armLength - bearingOD - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
             translate([-armLength, 0, 0])
                cylinder(h = bearingStep * 2, d = bearingOD);

        }
   }
           // screw holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])
                       cylinder(h = screwTabHeight, r = setScrewRadius);

   }
}

module armOuterJointBase(bearingOD, bearingStep, setScrewRadius, screwTabs, screwTabHeight) {
    mountHoleDepth = bearingStep * 2;

    //render()
    union() {
        difference() {
            union() {
                translate([0, 0, -(bearingStep * 2)])
                    difference() { // base w/ cutout for seeing into the joint

                        cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
                    intersection() { // cutout
                        difference() {
                            cylinder(h = bearingStep * 2, d = .85 * bearingOD);
                            cylinder(h = bearingStep * 2, d = .35 * bearingOD);
                        }
                        translate([-bearingOD, -bearingOD/2, 0])
                            cube([bearingOD, bearingOD, bearingStep * 2], center = false);
                    }
                }
                translate([0, 0, bearingStep * 2])
                    rotate([0, 180, 0])
                        bearingOuterStep(bearingOD, bearingStep, bearingStep);
                // spokes
                rotate([0, 0, 150])
                radial_array_partial(vec=[0, 0, 1], n = 6, 2)
                translate([hubRadius - (bearingStep / 2), -(spokeWidth / 2), -(bearingStep * 2)])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, bearingStep], center = false);
            }
            // motor shaft hole
            translate([0, 0, -(bearingStep * 2)])
                cylinder(h = shoulderBaseHeight + (bearingStep * 2), d = shaftBossDiameter);
            // mounting holes
            translate([0, 0, -(bearingStep * 2)]) {
                translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
                cylinder(h = mountHoleDepth, d = mountScrewDiameter);
                translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
                cylinder(h = mountHoleDepth, d = mountScrewDiameter);
            }
        }

    }
}

//armInnerJoint(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight);
module armInnerJoint(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight) {
    //translate([0, 0, hubHeight - (2 * stepHeight)])
    difference() {
        union() {
         difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + (setScrewRadius * 6));
            cylinder(h = bearingStep * 2, d = bearingOD);
//            translate([0, -bearingOD, 0])
//                cube([bearingOD, bearingOD * 2, bearingStep * 2]);
        }
        bearingOuterStep(bearingOD, stepHeight, stepWidth);
        // hub
        translate([0, 0, -(hubHeight - (2 * stepHeight))])
            stepperHub(hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight);
        // spokes
        radial_array(vec=[0, 0, 1], n = spokes)
                translate([hubRadius - (stepWidth / 2), -(spokeWidth / 2), stepHeight])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, stepHeight], center = false);
        // screw tabs for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])

                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }

                    }
        // screw holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])
                       cylinder(h = screwTabHeight, r = setScrewRadius);
    }
}

module forearmLower(bearingID, bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox) {
    armWidth = bearingOD / 2;

    rotate([180, 0, 0]) union() {
        boundingBoxHalf = boundingBox / 2;
        difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
            cylinder(h = bearingStep * 2, d = bearingID - (2 * bearingStep));
        }
        translate([0, 0, bearingStep * 2])
            bearingInnerStep(bearingID, bearingStep, bearingStep);
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * bearingStep) - screwTabHeight])
                    difference() {
                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }
                        cylinder(h = screwTabHeight, r = setScrewRadius);
                    }
        // hub
        translate([0, 0, hubHeight]) rotate([180, 0, 0])
            stepperHub(hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight);
        // spokes
        radial_array(vec=[0, 0, 1], n = spokes)
                translate([hubRadius - (stepWidth / 2), -(spokeWidth / 2), 0])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, 2 *stepHeight], center = false);
        // forearm extension
        difference() {
            translate([-forearmLength, -armWidth / 2, 0])
                cube([forearmLength, armWidth, bearingStep * 2], center=false);
            cylinder(h = bearingStep * 2, d = bearingOD);
 /* original */
sharpieDiameter = 13;
            translate([-forearmLength, 0, 0])
                 cylinder(h = bearingStep * 2, d = sharpieDiameter);
                 // 4 on next line comes from dividing the bearingOD on the above line
            translate([-forearmLength + sharpieDiameter, -(armWidth / 2) + boundingBoxHalf, 0])
                cube([forearmLength - (bearingOD/2) - (boundingBox + boundingBoxHalf), armWidth - boundingBox, bearingStep * 2], center = false);
/**/
        }

            intersection() {

                translate([-forearmLength + boundingBox, -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([forearmLength - (bearingOD / 2) - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
                for (i = [ bearingOD / 2 - boundingBoxHalf: armWidth : forearmLength]) {
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, 45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, -45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                }
            }

    }
}

module copy_mirror(vec=[0,1,0]) {
    children();
    mirror(vec)
        children();
}

module radial_array(vec = [0,0,1], n = 4) {
    for ( i = [0 : n - 1] )
    {
        rotate( i * 360 / n, vec)
            children();
    }
}

module radial_array_partial(vec = [0,0,1], n = 4, j = 2) {
    for ( i = [0 : n - 1] )
    {
        if (i < j)
            rotate( i * 360 / n, vec)
                children();
    }
}

use <StepMotor_28BYJ-48.scad>;
use <Hub_28BYJ-48.scad>;
include <Bearing_6807-2RS.scad>;

// global rendering parameters
//$fn = 64; // production
//$fn = 48; // development
$fn = 24; // LQ
echo($fn);

// library examples
// translate([100, 100, 10]) { StepMotor28BYJ(); }
// stepperHub(10, 7, 6, 3.1, 1.5, 2.75);
//translate([0, 0, 8]) bearing6807_2RS();
// bearingInnerStep(bearing6807_2RS_d - iFitAdjust, 2, 2);
//shoulderBase(2, 55, 9.1, 3.1);

// interference fit adjustment for 3D printer
iFitAdjust = .4;

// shoulder base parameters
shoulderBaseHeight = 3;
shoulderBaseDiameter = 55;
shaftBossDiameter = 10;
mountScrewDiameter = 3.1;
bearingStep = 2; // size in mm of bearing interface step
// joint parameters
hubHeight = 10;
hubRadius = 7;
shaftHeight = 6;
shaftRadius = 3.1;
setScrewRadius = 1.5;
setScrewHeight = 2.75;
spokeWidth = 3;
spokes = 6;
screwTabs = 4;
screwTabHeight = 4;
armLength = 100;
// misc
baseDeckExtension = 60;
boundingBox = 8;
boundingBoxHalf = boundingBox / 2;
// 8 is distance from shaft center to screw center on x axis
// 35 is screw center to screw center on y axis
shaftCenterToMountHoldCenterXAxis = 8;
mountHoleCenterToMountHoleCenter = 35;
leadScrewDiameter = 8;
// forearm
forearmLength = 75;

/* Pieces in this model
** Shoulder:
*** Base plate
*** Top plate
*** Lower arm
*** Upper arm
** Forearm:
*** ?
** Hand:
*** ?
*/

// SHOULDER
// shoulder base
module shoulderBasePlate() { // make me
color([.7, .7, 1])
    shoulderBase(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
}
shoulderBasePlate();
// shoulder lower stepper
rotate([0, 180, 0])
    translate([-8, 0, 10])
        StepMotor28BYJ();
// lower shoulder bearing
translate([0, 0, shoulderBaseHeight + bearingStep])
    %bearing6807_2RS();
// shoulder top
color([.6, .6, .9])
    translate([0, 0, 2 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep)])
    rotate([180, 0, 0])
        shoulderBase(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// upper shoulder bearing
translate([0, 0, shoulderBaseHeight + (3 * bearing6807_2RS_B) + (7 * bearingStep)])
    %bearing6807_2RS();
// shoulder upper stepper
rotate([0, 0, 180])
    translate([-8, 0, 10 + 2 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep)])
        StepMotor28BYJ();
// shoulder spacers
module shoulderSpacerSet() { // make me
color([.7, .6, .2])
shoulderSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
color([.7, .6, .2])
translate([baseDeckExtension / 3, 0, 0])
shoulderSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
}
shoulderSpacerSet();
// end shoulder

// lower arm including the shoulder - arm joint
//render()
module armSection() { // make me
color([1, .7, .7])
    translate([0, 0, shoulderBaseHeight + bearing6807_2RS_B])
        armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
}
armSection();
// upper arm
//render()
color([.9, .7, .7])
    translate([0, 0, shoulderBaseHeight + ( 2*bearing6807_2RS_B) + (12 * bearingStep) - (.5 * bearingStep)])
        rotate([180, 0, 0])
            armLower(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength);
// elbow joint pieces
// lower bearing
translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + bearingStep])
    %bearing6807_2RS();
// arm upper stepper
translate([-armLength + 8, 0, shoulderBaseHeight + ( 3*bearing6807_2RS_B) + (16 * bearingStep) - (.5 * bearingStep)])
    rotate([0, 0, 180])
        StepMotor28BYJ();
// arm lower stepper
rotate([0, 180, 0])
    translate([armLength - 8, 0, bearingStep * 2])
        StepMotor28BYJ();
// arm spacers
module armSpacerSet() { // make me
color([.6, .6, .3])
    armSpacers(bearing6807_2RS_D + iFitAdjust, 0 * shoulderBaseHeight + (4 * bearing6807_2RS_B) + (8 * bearingStep));
}
armSpacerSet();
// end arm

// forearm pieces
// lower
module forearmSection() { // make me
color([.1, .7, .1])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
//translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (14 *bearingStep)])
    forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
}
forearmSection();
// upper
render()
color([.2, .8, .2])
translate([-armLength, 0, shoulderBaseHeight + (bearing6807_2RS_B * 2) + (4 *bearingStep)])
    rotate([180, 0, 0])
        forearmLower(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight + (bearing6807_2RS_B / 2) + (bearingStep/2), hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox);
// forearm upper bearing
translate([-armLength, 0, shoulderBaseHeight + (2 * bearing6807_2RS_B) + (7 * bearingStep)])
    %bearing6807_2RS();
// forearm spacers
// none at this time

//bearingInnerStep(bearing6807_2RS_d - iFitAdjust, 2, 2);
module bearingInnerStep(bearingID, stepHeight, stepWidth) {
    difference() {
        union() {
            // this fits inside of the bearing
            cylinder(h = stepHeight * 2, d = bearingID);
            // this rests on the bearing inner lip
            cylinder(h = stepHeight, d = bearingID + stepWidth);
        }
        // remove center
        cylinder(h = stepHeight * 2, d = bearingID - (stepWidth * 2));
    }
}

//translate([0, 0, 12]) bearingOuterStep(bearing6807_2RS_D + iFitAdjust, 2, 2);
module bearingOuterStep(bearingOD, stepHeight, stepWidth) {
    //render(convexivity = 3)
    difference() {
        cylinder(h = stepHeight * 2, d = bearingOD + stepWidth);
        cylinder(h = stepHeight * 2, d = bearingOD - stepWidth);
        cylinder(h = stepHeight, d = bearingOD);
    }
}

module shoulderSpacers(bearingOD, screwSpacerHeight) {
    union() {
        // screw holes for joining to arm
        rotate([0, 0, -30])
        radial_array_partial(vec = [0, 0, 1], n = 6, 2)
            translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 1.0])
        difference() {
            union () {
                cylinder(h = screwSpacerHeight, r = setScrewRadius * 2);

                }
            cylinder(h = screwTabHeight, r = setScrewRadius);
        }
    }
}

module armSpacers(bearingOD, screwSpacerHeight) {
    union() {
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = 4)
            translate([bearingOD / 2 + (setScrewRadius * 2), 0, shoulderBaseHeight + bearing6807_2RS_B + 2 * bearingStep])
        difference() {
            union () {
                cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius * 2);

                }
            cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius);
        }
        // TODO: put in spacers along arm, make sure holes exist in arm
        translate([- armLength, 0, 0])
        rotate([0, 0, -30])
        radial_array_partial(vec = [0, 0, 1], n = 6, 2)
            translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight + bearing6807_2RS_B + 2 * bearingStep])
        difference() {
            union () {
                cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius * 2);

                }
            cylinder(h = bearing6807_2RS_B * 2 + 4 * bearingStep, r = setScrewRadius);
        }
    }
}

// armJointSpacer(bearing6807_2RS_D - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
module armJointSpacer(bearingID, bearingOD, bearingStep, shaftBossDiameter, mountScrewDiameter) {
    union() {
        difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
            cylinder(h = bearingStep * 2, d = bearingID);
        }
        translate([0, 0, bearingStep * 2])
                bearingInnerStep(bearingID, bearingStep, bearingStep);
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * bearingStep) - screwTabHeight])
                    difference() {
                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }
                        cylinder(h = screwTabHeight, r = setScrewRadius);
                    }
    }
}

//shoulderBase(2, 55, 9.1, 3.1);
// WARNING: has some hard-coded non-parametric values in here!
module shoulderBase(bearingID, bearingOD, shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter) {
    mountHoleDepth = shoulderBaseHeight;

    //render(convexivity = 3)
    difference() {
        union () {
            cylinder(h = shoulderBaseHeight, d = shoulderBaseDiameter);
            translate([0, 0, shoulderBaseHeight])
                bearingInnerStep(bearing6807_2RS_d - iFitAdjust, bearingStep, bearingStep);
            // 40 is the length of deck extension from the baseplate in x
            translate([0, -shoulderBaseDiameter / 2, 0])
                cube([baseDeckExtension, shoulderBaseDiameter, shoulderBaseHeight], center = false);
        }
        // motor shaft hole
        cylinder(h = shoulderBaseHeight + (bearingStep * 2), d = shaftBossDiameter);
        // mounting holes

        translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
            cylinder(h = mountHoleDepth, d = mountScrewDiameter);
        // lead screw hole
        translate([baseDeckExtension - (leadScrewDiameter * 1.5), 0, 0])
            cylinder(h = shoulderBaseHeight, d = leadScrewDiameter + (leadScrewDiameter / 2));
        // upper to lower spacer screw holes
        rotate([0, 0, -30])
            radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 0])
                    cylinder(h = screwTabHeight, r = setScrewRadius);
           translate([baseDeckExtension / 3, 0, 0])
            rotate([0, 0, -30])
            radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                translate([bearingOD / 2 + (setScrewRadius * 8), 0, shoulderBaseHeight * 0])
                    cylinder(h = screwTabHeight, r = setScrewRadius);
    }
    // NOTE: need to add LM8UU mounts
}

module armLower(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength) {
    armWidth = bearingOD / 2;
    //render(convexivity = 3)
    difference() {
    union() {
        armInnerJoint(bearingOD, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight);
        translate([-armLength, 0, 0])
            armOuterJointBase(bearingOD, bearingStep, setScrewRadius, screwTabs, screwTabHeight);
        difference() {
            translate([-armLength, -armWidth / 2, 0])
                cube([armLength, armWidth, bearingStep * 2], center=false);
            cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-armLength, 0, 0])
                cylinder(h = bearingStep * 2, d = bearingOD);
            translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                cube([armLength - bearingOD - (boundingBox + boundingBoxHalf), armWidth - boundingBox, bearingStep * 2], center = false);
        }
        difference() {
            intersection() {

                translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([armLength - bearingOD - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
                for (i = [ bearingOD / 2 - boundingBoxHalf: armWidth : armLength]) {
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, 45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, -45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                }
            }

        }
               difference() {
               hull() {
                   translate([- armLength, 0, bearingStep])
                    linear_extrude(height = 2 * bearingStep, center = true, twist = 0)
                        polygon(points=[[0, -bearingOD/2 - setScrewRadius/2], [bearingOD / 2 + (setScrewRadius * 8), -armWidth / 2], [bearingOD / 2 + (setScrewRadius * 8), armWidth / 2], [0, bearingOD/2 + setScrewRadius/2]]);
                translate([- armLength, 0, 0])
                    rotate([0, 0, -30])
                    radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                        translate([bearingOD / 2 + (setScrewRadius * 8), 0, 0])
                            cylinder(h = 2 * bearingStep, r = setScrewRadius * 2);

                    }
                translate([- armLength, 0, 0])
                    rotate([0, 0, -30])
                    radial_array_partial(vec = [0, 0, 1], n = 6, 2)
                        translate([bearingOD / 2 + (setScrewRadius * 8), 0, 0])
                        cylinder(h = 2 * bearingStep, r = setScrewRadius);

                 translate([-armLength + (bearingOD / 2) + (boundingBox / 2), -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([armLength - bearingOD - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
             translate([-armLength, 0, 0])
                cylinder(h = bearingStep * 2, d = bearingOD);

        }
   }
           // screw holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])
                       cylinder(h = screwTabHeight, r = setScrewRadius);

   }
}

module armOuterJointBase(bearingOD, bearingStep, setScrewRadius, screwTabs, screwTabHeight) {
    mountHoleDepth = bearingStep * 2;

    //render()
    union() {
        difference() {
            union() {
                translate([0, 0, -(bearingStep * 2)])
                    difference() { // base w/ cutout for seeing into the joint

                        cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
                    intersection() { // cutout
                        difference() {
                            cylinder(h = bearingStep * 2, d = .85 * bearingOD);
                            cylinder(h = bearingStep * 2, d = .35 * bearingOD);
                        }
                        translate([-bearingOD, -bearingOD/2, 0])
                            cube([bearingOD, bearingOD, bearingStep * 2], center = false);
                    }
                }
                translate([0, 0, bearingStep * 2])
                    rotate([0, 180, 0])
                        bearingOuterStep(bearingOD, bearingStep, bearingStep);
                // spokes
                rotate([0, 0, 150])
                radial_array_partial(vec=[0, 0, 1], n = 6, 2)
                translate([hubRadius - (bearingStep / 2), -(spokeWidth / 2), -(bearingStep * 2)])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, bearingStep], center = false);
            }
            // motor shaft hole
            translate([0, 0, -(bearingStep * 2)])
                cylinder(h = shoulderBaseHeight + (bearingStep * 2), d = shaftBossDiameter);
            // mounting holes
            translate([0, 0, -(bearingStep * 2)]) {
                translate([shaftCenterToMountHoldCenterXAxis, mountHoleCenterToMountHoleCenter/2, 0])
                cylinder(h = mountHoleDepth, d = mountScrewDiameter);
                translate([shaftCenterToMountHoldCenterXAxis, -mountHoleCenterToMountHoleCenter/2, 0])
                cylinder(h = mountHoleDepth, d = mountScrewDiameter);
            }
        }

    }
}

//armInnerJoint(bearing6807_2RS_D + iFitAdjust, bearingStep, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight);
module armInnerJoint(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight) {
    //translate([0, 0, hubHeight - (2 * stepHeight)])
    difference() {
        union() {
         difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + (setScrewRadius * 6));
            cylinder(h = bearingStep * 2, d = bearingOD);
//            translate([0, -bearingOD, 0])
//                cube([bearingOD, bearingOD * 2, bearingStep * 2]);
        }
        bearingOuterStep(bearingOD, stepHeight, stepWidth);
        // hub
        translate([0, 0, -(hubHeight - (2 * stepHeight))])
            stepperHub(hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight);
        // spokes
        radial_array(vec=[0, 0, 1], n = spokes)
                translate([hubRadius - (stepWidth / 2), -(spokeWidth / 2), stepHeight])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, stepHeight], center = false);
        // screw tabs for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])

                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }

                    }
        // screw holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - screwTabHeight])
                       cylinder(h = screwTabHeight, r = setScrewRadius);
    }
}

module forearmLower(bearingID, bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength, boundingBox) {
    armWidth = bearingOD / 2;

    rotate([180, 0, 0]) union() {
        boundingBoxHalf = boundingBox / 2;
        difference() {
            cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
            cylinder(h = bearingStep * 2, d = bearingID - (2 * bearingStep));
        }
        translate([0, 0, bearingStep * 2])
            bearingInnerStep(bearingID, bearingStep, bearingStep);
        // screw holes for joining to arm
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * bearingStep) - screwTabHeight])
                    difference() {
                        union () {
                            cylinder(h = screwTabHeight, r = setScrewRadius * 2);
                            translate([-2 * setScrewRadius, - 2 * setScrewRadius, 0])
                                cube([setScrewRadius * 2, 4 * setScrewRadius, screwTabHeight], center = false);
                        }
                        cylinder(h = screwTabHeight, r = setScrewRadius);
                    }
        // hub
        translate([0, 0, hubHeight]) rotate([180, 0, 0])
            stepperHub(hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight);
        // spokes
        radial_array(vec=[0, 0, 1], n = spokes)
                translate([hubRadius - (stepWidth / 2), -(spokeWidth / 2), 0])
                    cube([(bearingOD / 2) - hubRadius, spokeWidth, 2 *stepHeight], center = false);
        // forearm extension
        difference() {
            translate([-forearmLength, -armWidth / 2, 0])
                cube([forearmLength, armWidth, bearingStep * 2], center=false);
            cylinder(h = bearingStep * 2, d = bearingOD);
 /* original */
sharpieDiameter = 13;
            translate([-forearmLength, 0, 0])
                 cylinder(h = bearingStep * 2, d = sharpieDiameter);
                 // 4 on next line comes from dividing the bearingOD on the above line
            #translate([-forearmLength + sharpieDiameter, -(armWidth / 2) + boundingBoxHalf, 0])
                cube([forearmLength - (bearingOD/2) - (boundingBox + boundingBoxHalf), armWidth - boundingBox, bearingStep * 2], center = false);
/**/
        }

            intersection() {

                translate([-forearmLength + boundingBox, -(armWidth / 2) + boundingBoxHalf, 0])
                    cube([forearmLength - (bearingOD / 2) - boundingBox, armWidth - boundingBox, bearingStep * 2], center = false);
                for (i = [ bearingOD / 2 - boundingBoxHalf: armWidth : forearmLength]) {
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, 45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                    translate([ -i, 0, bearingStep])
                        rotate([0, 0, -45])
                            cube([spokeWidth, armWidth + boundingBoxHalf, bearingStep * 2], center = true);
                }
            }

    }
}

module copy_mirror(vec=[0,1,0]) {
    children();
    mirror(vec)
        children();
}

module radial_array(vec = [0,0,1], n = 4) {
    for ( i = [0 : n - 1] )
    {
        rotate( i * 360 / n, vec)
            children();
    }
}

module radial_array_partial(vec = [0,0,1], n = 4, j = 2) {
    for ( i = [0 : n - 1] )
    {
        if (i < j)
            rotate( i * 360 / n, vec)
                children();
    }
}


The holes were added for the keys as well as a cutout for the mounting panel of the keys.

use <../../../../../basics/rounded-edges/rounded-cube-enclosure/rounded-cube-enclosure.scad>

use <../../../../../microcontrollers/adafruit/trinket-mini/mounting-standoffs/trinket-mini-mounting-standoffs.scad>

use <../../../../../office/keyboard/panels/keyboard-panel.scad>

trinketMiniShortcutKeyboard();

module frameWithTrinketMounts(boardLengthZ, cornerRadius)
{
	union()
	{
		boardLengthX = 60;
		boardLengthY = 60;

		roundedCubeEnclosure(boardLengthX = boardLengthX,
							boardLengthY = boardLengthY,
							boardLengthZ = boardLengthZ,
							cornerRadius = cornerRadius,
							xAxisCutout_yPercentage = 0.8,
							xAxisCutout_zPercentage = 0.8,
							yAxisCutout_xPercentage = 0.85,
							yAxisCutout_zPercentage = 0.75);

		xTranslate = (boardLengthX + cornerRadius) * 0.6;
		yTranslate = (boardLengthY + cornerRadius) * 0.3;
		zTranslate = 2;

		color("red")
		translate([xTranslate, yTranslate, zTranslate])
		trinketMiniStandoffs();
	}
}

module trinketMiniShortcutKeyboard()
{
	boardLengthZ = 30;
	buttonSide = 12;
	cornerRadius = 3;

	difference()
	{
		frameWithTrinketMounts(boardLengthZ, cornerRadius);

		xTranslate = -12;
		yTranslate = 1;
		zTranslate = boardLengthZ * 0.8;
		translate([xTranslate, yTranslate, zTranslate])
		keyboardHoles(buttonCount = 4,
					 buttonSide = buttonSide,
				 	 panelHeight = 5);

		 panelCutout_xLength = buttonSide + 4;
		 panelCutout_yLength = (panelCutout_xLength * 4) - 5;
		 panelCutout_zLength = 10;
		 panelCutout_xTranslate = 2;
		 panelCutout_yTranslate = 0;
		 panelCutout_zTranslate = (boardLengthZ + cornerRadius) - panelCutout_zLength - 1;  // the minus 1 is for the panel mount height
		 color("pink")
		 translate([panelCutout_xTranslate, panelCutout_yTranslate, panelCutout_zTranslate])
		 cube([panelCutout_xLength, panelCutout_yLength, panelCutout_zLength]);
	}
}

use <../../../../../basics/rounded-edges/rounded-cube-enclosure/rounded-cube-enclosure.scad>

use <../../../../../microcontrollers/adafruit/trinket-mini/mounting-standoffs/trinket-mini-mounting-standoffs.scad>

trinketMiniShortcutKeyboard();

module frameWithTrinketMounts()
{
	union()
	{
		boardLengthX = 60;
		boardLengthY = 60;
		cornerRadius = 3;
		roundedCubeEnclosure(boardLengthX = boardLengthX,
							boardLengthY = boardLengthY,
							boardLengthZ = 30,
							cornerRadius = cornerRadius,
							xAxisCutout_yPercentage = 0.8,
							xAxisCutout_zPercentage = 0.8,
							yAxisCutout_xPercentage = 0.85,
							yAxisCutout_zPercentage = 0.75);

		xTranslate = (boardLengthX + cornerRadius) * 0.6;
		yTranslate = (boardLengthY + cornerRadius) * 0.3;
		zTranslate = 2;

		color("red")
		translate([xTranslate, yTranslate, zTranslate])
		trinketMiniStandoffs();
	}
}

module trinketMiniShortcutKeyboard()
{
	frameWithTrinketMounts();

}


stepper: misc improvements

stepper: misc improvements

 // Some code from MCAD/stepper.scad
 // Originally by Hans Häggström, 2010.
 // Dual licenced under Creative Commons Attribution-Share Alike 3.0 and LGPL2 or later

include <system.scad>
include <units.scad>
include <materials.scad>
include <stepper-data.scad>
include <misc.scad>

use <transforms.scad>
use <shapes.scad>

/*test2();*/

module test()
{
    for (size = AllNemaSizes)
    {
        ty(size*100)
        stack(axis=X, dist=100)
        {
            motor(model=Nema34, size=size, dual_axis=true);
            motor(model=Nema23, size=size, dual_axis=true);
            motor(model=Nema17, size=size, dual_axis=true);
            motor(model=Nema14, size=size, dual_axis=true);
            motor(model=Nema11, size=size, dual_axis=true);
            motor(model=Nema08, size=size, dual_axis=true);
        }
    }
}

module test2()
{
    model = Nema17;
    size = NemaMedium;
    motor_mount(model=model, size=size, dual_axis=true);
}

function motorWidth(model) = get(NemaSideSize, model);
function motorLength(model, size=NemaMedium) = get(size, model);

module motor_mount(part=U, model, thickness, size=NemaMedium, extra_size=U, dual_axis=false, orient=Z, align=U)
{
    assert(model!=U, "motor_mount(): model==U");
    assert(thickness!=U, "motor_mount(): thickness==U");
    assert(size!=U, "motor_mount(): size==U");

    length = get(size, model);
    side = get(NemaSideSize, model);
    extrSize = get(NemaRoundExtrusionHeight, model);
    extrRad = get(NemaRoundExtrusionDiameter, model) * 0.5;
    holeDist = get(NemaDistanceBetweenMountingHoles, model) * 0.5;
    holeRadius = get(NemaMountingHoleDiameter, model) * 0.5;

    s=[side+fallback(extra_size.x,0), side+fallback(extra_size.y,0), length];
    size_align(size=s, orient=orient, align=align)
    if(part==U)
    {
        material(Mat_Plastic)
        render()
        difference()
        {
            motor_mount(part="pos", model=model, thickness=thickness, size=size, dual_axis=dual_axis);
            motor_mount(part="neg", model=model, thickness=thickness, size=size, dual_axis=dual_axis);
        }

        if($show_vit)
        motor_mount(part="vit", model=model, thickness=thickness, size=size, dual_axis=dual_axis);
    }
    else if(part=="pos")
    {
        rcubea([s.x,s.y,thickness], align=Z);
    }
    else if(part=="neg")
    {
        cylindera(h=thickness+.1, r=extrRad, align=Z, extra_h=.1, extra_align=-Z);

        // main motor
        tz(-s.z)
        cubea(size=[side+.3*mm,side+.3*mm,length], align=Z);

        // Bolt holes
        material(Mat_Aluminium)
        for(x=[-1,1])
        for(y=[-1,1])
        tx(x*holeDist)
        ty(y*holeDist)
        cylindera(h=thickness+.1, r=holeRadius, align=Z, extra_h=.1, extra_align=-Z);

    }
    else if(part=="vit")
    {
        motor(model=model, size=size, dualAxis=dual_axis, orient=Z);
    }
}

module motor(part=U, model, size=NemaMedium, dual_axis=false, orient=Z, align=U)
{
    assert(model!=U, "model == U");
    assert(size!=U, "size == U");
    length = get(size, model);

    side = get(NemaSideSize, model);
    cutR = get(NemaMountingHoleCutoutRadius, model);
    lip = get(NemaMountingHoleLip, model);
    holeDepth = get(NemaMountingHoleDepth, model);

    axleRadius = get(NemaAxleDiameter, model) * 0.5;

    extrSize = get(NemaRoundExtrusionHeight, model);
    extrRad = get(NemaRoundExtrusionDiameter, model) * 0.5;

    holeDist = get(NemaDistanceBetweenMountingHoles, model) * 0.5;
    holeRadius = get(NemaMountingHoleDiameter, model) * 0.5;

    mid = side / 2;

    roundR = get(NemaEdgeRoundingRadius, model);

    s=[side, side, length];
    size_align(size=s, orient=orient, align=align)
    if(part==U)
    {
        difference()
        {
            motor(part="pos", model=model, size=size, dual_axis=dual_axis);
            motor(part="neg", model=model, size=size, dual_axis=dual_axis);
        }
        motor(part="vit", model=model, size=size, dual_axis=dual_axis);

        motor_axle(model=model, size=size, dual_axis=dual_axis);
    }
    if(part=="echo")
    {
        echo(str("  Motor: Nema",get(NemaModel, model),", length= ",length,"mm, dual axis=",dual_axis));
    }
    else if(part=="pos")
    {
        material(Mat_BlackPaint)
        tz(-s.z)
        cubea(s, align=Z, extra_size=Z*extrSize, extra_align=Z);
    }
    else if(part=="neg")
    {
        // Axle hole
        material(Mat_Aluminium)
        cylindera(r=axleRadius+.2*mm, h=1000);

        // Corner cutouts
        if (lip > 0)
        material(Mat_BlackPaint)
        tz(-s.z)
        for(x=[-1,1])
        for(y=[-1,1])
        tx(x*side/2)
        ty(y*side/2)
        tz(-lip)
        cylindera(h=length, r=cutR, align=Z);

        // Rounded edges
        if (roundR > 0)
        material(Mat_BlackPaint)
        tz(-s.z)
        for(x=[-1,1])
        for(y=[-1,1])
        tx(x*side/2)
        ty(y*side/2)
        mirror([x>0?0:1,y>0?0:1,0])
        rz(45)
        cubea(size=[roundR, roundR*2, 4+length + extrSize+2], align=Z, extra_size=.1*Z, extra_align=-Z);

        // Bolt holes
        material(Mat_Aluminium)
        for(x=[-1,1])
        for(y=[-1,1])
        tx(x*holeDist)
        ty(y*holeDist)
        cylindera(h=holeDepth+.1*mm, r=holeRadius, align=-Z, extra_h=.1, extra_align=Z);

        // Grinded flat
        material(Mat_BlackPaint)
        difference()
        {
            cubea(size=[side+.1, side+.1, extrSize+.1], align=Z);
            cylindera(h=extrSize, r=extrRad, align=Z);
        }
    }
}

module motor_axle(model=Nema23, size=NemaMedium, dual_axis=false, orient=Z, align=U)
{
    assert(model!=U, "model == U");
    assert(size!=U, "size == U");
    length = get(size, model);

    axleLengthFront = get(NemaFrontAxleLength, model);
    axleLengthBack = get(NemaBackAxleLength, model);
    axleRadius = get(NemaAxleDiameter, model) * 0.5;

    extrSize = get(NemaRoundExtrusionHeight, model);

    roundR = get(NemaEdgeRoundingRadius, model);

    axleFlatDepth = get(NemaAxleFlatDepth, model);
    axleFlatLengthFront = get(NemaAxleFlatLengthFront, model);
    axleFlatLengthBack = get(NemaAxleFlatLengthBack, model);

    material(Mat_Steel)
    render()
    intersection()
    {
        material(Mat_Aluminium)
        tz(-length)
        cylindera(r=axleRadius, h=length+extrSize+axleLengthFront, align=Z, extra_h=dual_axis?axleLengthBack:0, extra_align=-Z);

        material(Mat_Aluminium)
        union()
        {
            tx(axleFlatDepth>0?-axleFlatDepth:0)
            cubea(size=[2*axleRadius, 2*axleRadius, axleLengthFront], align=Z);

            cubea(size=[2*axleRadius, 2*axleRadius, length+.4*mm], align=-Z, extra_size=Z*(extrSize+.4*mm), extra_align=Z);

            tx(axleFlatDepth>0?-axleFlatDepth:0)
            tz(-length)
            cubea(size=[2*axleRadius, 2*axleRadius, axleLengthBack], align=-Z);
        }
    }
}

 // Some code from MCAD/stepper.scad
 // Originally by Hans Häggström, 2010.
 // Dual licenced under Creative Commons Attribution-Share Alike 3.0 and LGPL2 or later

include <system.scad>
include <units.scad>
include <materials.scad>
include <stepper-data.scad>
include <misc.scad>

use <transforms.scad>
use <shapes.scad>

/*test2();*/

module test()
{
    for (size = AllNemaSizes)
    {
        ty(size*100)
        stack(axis=X, dist=100)
        {
            motor(model=Nema34, size=size, dual_axis=true);
            motor(model=Nema23, size=size, dual_axis=true);
            motor(model=Nema17, size=size, dual_axis=true);
            motor(model=Nema14, size=size, dual_axis=true);
            motor(model=Nema11, size=size, dual_axis=true);
            motor(model=Nema08, size=size, dual_axis=true);
        }
    }
}

module test2()
{
    model = Nema17;
    size = NemaMedium;
    motor_mount(model=model, size=size, dual_axis=true);
}

function motorWidth(model) = get(NemaSideSize, model);
function motorLength(model, size=NemaMedium) = get(size, model);

module motor_mount(part=U, model, thickness, size=NemaMedium, dual_axis=false, orient=Z, align=U)
{
    assert(model!=U, "motor_mount(): model==U");
    assert(thickness!=U, "motor_mount(): thickness==U");
    assert(size!=U, "motor_mount(): size==U");

    length = get(size, model);
    side = get(NemaSideSize, model);
    extrSize = get(NemaRoundExtrusionHeight, model);
    extrRad = get(NemaRoundExtrusionDiameter, model) * 0.5;
    holeDist = get(NemaDistanceBetweenMountingHoles, model) * 0.5;
    holeRadius = get(NemaMountingHoleDiameter, model) * 0.5;

    s=[side, side, length];
    size_align(size=s, orient=orient, align=align)
    if(part==U)
    {
        material(Mat_Plastic)
        render()
        difference()
        {
            motor_mount(part="pos", model=model, thickness=thickness, size=size, dual_axis=dual_axis);
            motor_mount(part="neg", model=model, thickness=thickness, size=size, dual_axis=dual_axis);
        }

        if($show_vit)
        motor_mount(part="vit", model=model, thickness=thickness, size=size, dual_axis=dual_axis);
    }
    else if(part=="pos")
    {
        rcubea([side,side,thickness], align=Z);
    }
    else if(part=="neg")
    {
        cylindera(h=thickness+.1, r=extrRad, align=Z, extra_h=.1, extra_align=-Z);

        // main motor
        tz(-s.z)
        cubea(s, align=Z);

        // Bolt holes
        material(Mat_Aluminium)
        for(x=[-1,1])
        for(y=[-1,1])
        tx(x*holeDist)
        ty(y*holeDist)
        cylindera(h=thickness+.1, r=holeRadius, align=Z, extra_h=.1, extra_align=-Z);

    }
    else if(part=="vit")
    {
        motor(model=model, size=size, dualAxis=dual_axis, orient=Z);
    }
}

module motor(part=U, model, size=NemaMedium, dual_axis=false, orient=Z, align=U)
{
    assert(model!=U, "model == U");
    assert(size!=U, "size == U");
    length = get(size, model);

    side = get(NemaSideSize, model);
    cutR = get(NemaMountingHoleCutoutRadius, model);
    lip = get(NemaMountingHoleLip, model);
    holeDepth = get(NemaMountingHoleDepth, model);

    axleRadius = get(NemaAxleDiameter, model) * 0.5;

    extrSize = get(NemaRoundExtrusionHeight, model);
    extrRad = get(NemaRoundExtrusionDiameter, model) * 0.5;

    holeDist = get(NemaDistanceBetweenMountingHoles, model) * 0.5;
    holeRadius = get(NemaMountingHoleDiameter, model) * 0.5;

    mid = side / 2;

    roundR = get(NemaEdgeRoundingRadius, model);

    s=[side, side, length];
    size_align(size=s, orient=orient, align=align)
    if(part==U)
    {
        difference()
        {
            motor(part="pos", model=model, size=size, dual_axis=dual_axis);
            motor(part="neg", model=model, size=size, dual_axis=dual_axis);
        }
        motor(part="vit", model=model, size=size, dual_axis=dual_axis);

        motor_axle(model=model, size=size, dual_axis=dual_axis);
    }
    if(part=="echo")
    {
        echo(str("  Motor: Nema",get(NemaModel, model),", length= ",length,"mm, dual axis=",dual_axis));
    }
    else if(part=="pos")
    {
        material(Mat_BlackPaint)
        tz(-s.z)
        cubea(s, align=Z, extra_size=Z*extrSize, extra_align=Z);
    }
    else if(part=="neg")
    {
        // Axle hole
        material(Mat_Aluminium)
        cylindera(r=axleRadius+.2*mm, h=1000);

        // Corner cutouts
        if (lip > 0)
        material(Mat_BlackPaint)
        tz(-s.z)
        for(x=[-1,1])
        for(y=[-1,1])
        tx(x*side/2)
        ty(y*side/2)
        tz(-lip)
        cylindera(h=length, r=cutR, align=Z);

        // Rounded edges
        if (roundR > 0)
        material(Mat_BlackPaint)
        tz(-s.z)
        for(x=[-1,1])
        for(y=[-1,1])
        tx(x*side/2)
        ty(y*side/2)
        mirror([x>0?0:1,y>0?0:1,0])
        rz(45)
        cubea(size=[roundR, roundR*2, 4+length + extrSize+2], align=Z);

        // Bolt holes
        material(Mat_Aluminium)
        for(x=[-1,1])
        for(y=[-1,1])
        tx(x*holeDist)
        ty(y*holeDist)
        cylindera(h=holeDepth+.1*mm, r=holeRadius, align=-Z, extra_h=.1, extra_align=Z);

        // Grinded flat
        material(Mat_BlackPaint)
        difference()
        {
            cubea(size=[side+.1, side+.1, extrSize+.1], align=Z);
            cylindera(h=extrSize, r=extrRad, align=Z);
        }
    }
}

module motor_axle(model=Nema23, size=NemaMedium, dual_axis=false, orient=Z, align=U)
{
    assert(model!=U, "model == U");
    assert(size!=U, "size == U");
    length = get(size, model);

    axleLengthFront = get(NemaFrontAxleLength, model);
    axleLengthBack = get(NemaBackAxleLength, model);
    axleRadius = get(NemaAxleDiameter, model) * 0.5;

    extrSize = get(NemaRoundExtrusionHeight, model);

    roundR = get(NemaEdgeRoundingRadius, model);

    axleFlatDepth = get(NemaAxleFlatDepth, model);
    axleFlatLengthFront = get(NemaAxleFlatLengthFront, model);
    axleFlatLengthBack = get(NemaAxleFlatLengthBack, model);

    render()
    intersection()
    {
        material(Mat_Aluminium)
        tz(-length)
        cylindera(r=axleRadius, h=length+extrSize+axleLengthFront, align=Z, extra_h=dual_axis?axleLengthBack:0, extra_align=-Z);

        material(Mat_Aluminium)
        union()
        {
            tx(axleFlatDepth>0?-axleFlatDepth:0)
            cubea(size=[2*axleRadius, 2*axleRadius, axleLengthFront], align=Z);

            cubea(size=[2*axleRadius, 2*axleRadius, length+.4*mm], align=-Z, extra_size=Z*(extrSize+.4*mm), extra_align=Z);

            tx(axleFlatDepth>0?-axleFlatDepth:0)
            tz(-length)
            cubea(size=[2*axleRadius, 2*axleRadius, axleLengthBack], align=-Z);
        }
    }
}


The dome was added and the mouning post zTranslate was added for customization.

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

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

module lightSignal(baseHeight = 2,
                    icon1 = "",
                    icon1_scale = 1,
                    icon1_x = 0,
                    icon1_y = 0,
                    icon2 = "",
                    icon2_scale = 1.0,
                    icon2_x = 0,
                    icon2_y = 0,
					mountingPosts = "No",
					mountingPostsTranslatePercentageZ = 0.6,
                    text1 = "",
					text1_fontName = "Bauhaus 93:style=Regular",
                    text1_fontSize = 7.5,
                    text1_x = 0,
                    text1_y = 0,
                    text2 = "",
					text2_fontName = "Bauhaus 93:style=Regular",
                    text2_fontSize = 7.5,
                    text2_x = 0,
                    text2_y = 0)
{
	difference()
	{
		showOriginal = "No";
		lightSignal_shell(baseHeight, mountingPosts, mountingPostsTranslatePercentageZ, showOriginal);

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

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

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

function lightSignal_stlBaseOuterRadius() = lightSignal_stlBaseInnerRadius() + 2.5;

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

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

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

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

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

// TODO: Move this model back here!
//module lightSignal_oneShellMountingPost()

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

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

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

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

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

		// connector for the shaft and top hole
		color("pink")
		translate([0, 0, zTopHoleTranslate-3])
		openCylinder(height=3.1, outerRadius = 19, innerRadius=8);
*/
//------------
		color([1,0.6863,0.6863])
		translate([0,0,13.5])
		difference()
		{
			dome(domePercentage=50, radius=30.0);

			openCylinder(height=35, innerRadius=21.0, outerRadius=51.0);

			translate([0,0,31])
			cylinder(h=9, r=6, center=true);

		}
//------------

		if(mountingPosts == "Yes")
		{
			lightSignal_shellMountingPosts(zTopHoleTranslate, mountingPostsTranslatePercentageZ);
		}

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

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

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

// TODo: Move this module to the correct ABC location
module lightSignal_oneShellMountingPost()
{
	height = 10;
//	translate([height, 0, 0])
	rotate([0, 90, 0])
	cylinder(r=3, h=height, center=true, $fn=20);
}

module lightSignal_shellMountingPosts(zTopHoleTranslate, zTranslatePercentage)
{
	xTranslate = lightSignal_stlBaseOuterRadius() + 2.5;
	zTranslate = zTopHoleTranslate * zTranslatePercentage;
	translate([xTranslate, 0, zTranslate])
	lightSignal_oneShellMountingPost();

//	zTranslate = zTopHoleTranslate * 0.75;
	translate([-xTranslate, 0, zTranslate])
	lightSignal_oneShellMountingPost();
}

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

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

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

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

module lightSignal(baseHeight = 2,
                    icon1 = "",
                    icon1_scale = 1,
                    icon1_x = 0,
                    icon1_y = 0,
                    icon2 = "",
                    icon2_scale = 1.0,
                    icon2_x = 0,
                    icon2_y = 0,
					mountingPosts = "No",
                    text1 = "",
					text1_fontName = "Bauhaus 93:style=Regular",
                    text1_fontSize = 7.5,
                    text1_x = 0,
                    text1_y = 0,
                    text2 = "",
					text2_fontName = "Bauhaus 93:style=Regular",
                    text2_fontSize = 7.5,
                    text2_x = 0,
                    text2_y = 0)
{
	difference()
	{
		showOriginal = "No";
		lightSignal_shell(baseHeight, mountingPosts, showOriginal);
//		lightSignal_shell(baseHeight, showOriginal = false);

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

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

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

function lightSignal_stlBaseOuterRadius() = lightSignal_stlBaseInnerRadius() + 2.5;

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

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

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

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

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

// TODO: Move this model back here!
//module lightSignal_oneShellMountingPost()

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

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

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

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

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

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

		if(mountingPosts == "Yes")
		{
			lightSignal_shellMountingPosts(zTopHoleTranslate);
		}

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

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

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

// TODo: Move this module to the correct ABC location
module lightSignal_oneShellMountingPost()
{
	height = 10;
//	translate([height, 0, 0])
	rotate([0, 90, 0])
	cylinder(r=3, h=height, center=true, $fn=20);
}

module lightSignal_shellMountingPosts(zTopHoleTranslate)
{
	xTranslate = lightSignal_stlBaseOuterRadius() + 2.5;
	zTranslate = zTopHoleTranslate * 0.75;
	translate([xTranslate, 0, zTranslate])
	lightSignal_oneShellMountingPost();

	zTranslate = zTopHoleTranslate * 0.75;
	translate([-xTranslate, 0, zTranslate])
	lightSignal_oneShellMountingPost();
}

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

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


Introduce new travel bracket design

Introduce new travel bracket design

module TravelBracket(){
difference(){
	union(){
		import("..//..//approved//TRV_BRKT.stl");

		// Fill in unneeded holes
		color([255,0,0])translate([16,17,3])rotate([90,0,0])cylinder(h=10,r=1.8,$fn=40);
		color([255,0,0])translate([16,17,11])rotate([90,0,0])cylinder(h=10,r=1.8,$fn=40);

		translate([22,9,0])cube([6,8,14]);
		translate([-22,9,0])mirror([1,0,0])cube([6,8,14]);
		translate([22,-9,0])mirror([0,1,0])cube([6,6,14]);
		translate([-22,-9,0])mirror([1,1,0])cube([6,6,14]);

		translate([13,11,0])cube([6,3,14]);

		// Linear bearing holes
		difference(){
			union(){
				translate([25,0,0])cylinder(h=14,r=10,$fn=40);
				translate([-25,0,0])cylinder(h=14,r=10,$fn=40);
			}

			union(){
				translate([25,0,-1])cylinder(h=18,r=8,$fn=40);
				translate([-25,0,-1])cylinder(h=18,r=8,$fn=40);
			}
		}

	}

		// Mount screw Linear bearing
		translate([-25,0,7])rotate([90,0,0])cylinder(h=40,r=1.8,$fn=40,center=true);
		translate([25,0,7])rotate([90,0,0])cylinder(h=40,r=1.8,$fn=40,center=true);

}

}

module NutSocket(width,depth,height)
{
	side_length=sqrt(pow(width,2)/2);
	translate([0,0,height/2])cube([width,depth,height],center=true);
	rotate([0,45,0])cube([side_length,depth,side_length],center=true);
}

difference(){
	TravelBracket();

	union(){
		translate([-25,12.5,5.5])NutSocket(6,3,14);
		translate([25,12.5,5.5])NutSocket(6,3,14);
		mirror([0,1,0])translate([-25,11,5.5])NutSocket(6,3,14);
		mirror([0,1,0])translate([25,11,5.5])NutSocket(6,3,14);
	}
}

error: pathspec 'models/experimental/Wintermute_Travel_Bracket/Travel_Brkt_Solid.scad' did not match any file(s) known to git


The include path was corrected.

The include path was corrected.

use <../../../switch-mounting-holes/adafruit-1009/adafruit-1009-panel.scad>

adafruit10009SwitchPanel(boardLengthX = 60,
                         panelHeight = 1);

use <../../../../switch-mounting-holes/adafruit-1009/adafruit-1009-panel.scad>

  //      farto

adafruit10009SwitchPanel(boardLengthX = 60,
                         panelHeight = 1);