Refining layout

Refining layout

module LogoBotPolarGraphAssembly () {

    assembly("assemblies/LogoBotPolarGraph.scad", "LogoBot Polar Graph", str("LogoBotPolarGraphAssembly()")) {

    // Rough placement of the polar graph parts

    // bit of wood to fix it all to
    color([0.8,0.7,0.6])
        translate([-250,-10,-20])
        cube([500,20,20]);

    // drawing surface
    color([0.9,0.9,0.9])
        translate([-250,-10,-420])
        cube([500,4,400]);

    // wheels - aka winches
    attach([[240,0,0],[0,0,-1],0,00], MotorClip_Con_Fixing1, ExplodeSpacing = 40)
        LeftWheelAssembly();

    attach([[-240,0,0],[0,0,-1],0,00], MotorClip_Con_Fixing2, ExplodeSpacing = 40)
        RightWheelAssembly();

    // gondola - aka base
    attach([[0,-GroundClearance-10,-150],[0,1,0],0,0,0], DefConDown) {
        LogoBotBase_STL();

        // need the pen lift and servo, but rotated 90 deg
        rotate([0,0,90]) {
            attach(LogoBot_Con_PenLift_Front, PenLiftSlider_Con_BaseFront)
                PenLiftAssembly();

            attach(LogoBot_Con_PenLiftServo, MicroServo_Con_Horn, ExplodeSpacing=0) {
                MicroServo();
                attach(MicroServo_Con_Horn, ServoHorn_Con_Default)
                    ServoHorn();
            }
        }

        // and some castors to hold the base away from the drawing surface
        attach(invertConnector(LogoBot_Con_GridFixing(3,4,0)), MarbleCaster_Con_Default, ExplodeSpacing=15)
            MarbleCasterAssembly();

        attach(invertConnector(LogoBot_Con_GridFixing(-3,4,0)), MarbleCaster_Con_Default, ExplodeSpacing=15)
                MarbleCasterAssembly();

        attach(invertConnector(LogoBot_Con_GridFixing(0,-6,0)), MarbleCaster_Con_Default, ExplodeSpacing=15)
                        MarbleCasterAssembly();

    }

    // electronic stuff at the top somewhere
    attach([[0,0,3],[0,0,-1],90,0,0], ArduinoPro_Con_Center, ExplodeSpacing=20)
        ArduinoPro(ArduinoPro_Mini, ArduinoPro_Pins_Opposite, true);

    // steps
    step(1, "Do something") {
            view(t=[0,0,0], r=[52,0,218], d=400);

            //attach(DefConDown, DefConDown)
            //      AnotherAssembly();
        }

    }
}

module LogoBotPolarGraphAssembly () {

    assembly("assemblies/LogoBotPolarGraph.scad", "LogoBot Polar Graph", str("LogoBotPolarGraphAssembly()")) {

    // Rough placement of the polar graph parts

    // bit of wood to fix it all to
    color([0.8,0.7,0.6])
        translate([-200,-10,-20])
        cube([400,20,20]);

    // drawing surface
    color([0.9,0.9,0.9])
        translate([-200,-10,-420])
        cube([400,4,400]);

    // wheels - aka winches
    attach([[200,0,0],[0,0,-1],0,00], MotorClip_Con_Fixing1, ExplodeSpacing = 40)
        RightWheelAssembly();

    attach([[-200,0,0],[0,0,-1],0,00], MotorClip_Con_Fixing2, ExplodeSpacing = 40)
        LeftWheelAssembly();

    // gondola - aka base
    attach([[0,-GroundClearance-10,-150],[0,1,0],0,0,0], DefConDown) {
        LogoBotBase_STL();

        // need the pen lift and servo, but rotated 90 deg
        rotate([0,0,90]) {
            attach(LogoBot_Con_PenLift_Front, PenLiftSlider_Con_BaseFront)
                PenLiftAssembly();

            attach(LogoBot_Con_PenLift_Front, offsetConnector(DefConUp, [0, 0, 2 + 2.5]), ExplodeSpacing=20)
                PinTack_STL(h=2.5+4+2.5);
            attach(LogoBot_Con_PenLift_Rear, offsetConnector(DefConUp, [0, 0, 2 + 2.5]), ExplodeSpacing=20)
                PinTack_STL(h=2.5+4+2.5);

            attach(LogoBot_Con_PenLiftServo, MicroServo_Con_Horn, ExplodeSpacing=0) {
                MicroServo();
                attach(MicroServo_Con_Horn, ServoHorn_Con_Default)
                    ServoHorn();
            }
        }

        // and some castors to hold the base away from the drawing surface
        attach(invertConnector(LogoBot_Con_GridFixing(3,4,0)), MarbleCaster_Con_Default, ExplodeSpacing=15)
            MarbleCasterAssembly();

        attach(invertConnector(LogoBot_Con_GridFixing(-3,4,0)), MarbleCaster_Con_Default, ExplodeSpacing=15)
                MarbleCasterAssembly();

        attach(invertConnector(LogoBot_Con_GridFixing(0,-6,0)), MarbleCaster_Con_Default, ExplodeSpacing=15)
                        MarbleCasterAssembly();

    }

    // electronic stuff at the top somewhere
    attach([[0,0,3],[0,0,-1],90,0,0], ArduinoPro_Con_Center, ExplodeSpacing=20)
        ArduinoPro(ArduinoPro_Mini, ArduinoPro_Pins_Opposite, true);

    // steps
    step(1, "Do something") {
            view(t=[0,0,0], r=[52,0,218], d=400);

            //attach(DefConDown, DefConDown)
            //      AnotherAssembly();
        }

    }
}


getting ready to make motor clips

getting ready to make motor clips

include <../config/config.scad>

DebugConnectors = 1;
DebugCoordinateFrames = 0;

$Explode=true;
$ShowStep = 3;

LogoBotAssembly();

include <../config/config.scad>

DebugConnectors = 1;
DebugCoordinateFrames = 0;

$Explode=true;
$ShowStep = 4;

LogoBotAssembly();


Rotator: added LEGO shaft openscad file

Rotator: added LEGO shaft openscad file

/*

 Basic Lego brick builder module for OpenScad by Jorg Janssen 2013 (CC BY-NC 3.0)
 To use this in your own projects add:

 use <path_to_this_file/lego_brick_builder.scad>
 brick (length, width, height [,smooth]);

 Length and width are in standard lego brick dimensions.
 Height is in flat brick heights, so for a normal lego brick height = 3.
 Add optional smooth = true for a brick without studs.
 Use height = 0 to just put studs/knobs on top of other things.

 */
$fn = 150;

 // this is it:
brick(2,2,1);

// and this is how it's done:

FLU = 1.6; // Fundamental Lego Unit = 1.6 mm

BRICK_WIDTH = 5*FLU; // basic brick width
BRICK_HEIGHT = 6*FLU; // basic brick height
PLATE_HEIGHT = 2*FLU; // basic plate height
WALL_THICKNESS = FLU; // outer wall of the brick
STUD_RADIUS = 0*FLU; // studs are the small cylinders on top of the brick with the lego logo ('nopje' in Dutch)
STUD_HEIGHT = FLU;
ANTI_STUD_RADIUS = 0.5*4.07*FLU;  // an anti stud is the hollow cylinder inside bricks that have length > 1 and width > 1
PIN_RADIUS = FLU; // a pin is the small cylinder inside bricks that have length = 1 or width = 1
SUPPORT_THICKNESS = 0.254; // support is the thin surface between anti studs, pins and walls, your printer might not print this thin, try thicker!
EDGE = 0.254; // this is the width and height of the bottom line edge of smooth bricks
CORRECTION = 0.1; // addition to each size, to make sure all parts connect by moving them a little inside each other

module brick(length = 4, width = 2, height = 3, smooth = false){

	// brick shell
	difference(){
		cube(size = [length*BRICK_WIDTH,width*BRICK_WIDTH,height*PLATE_HEIGHT]);
		translate([WALL_THICKNESS,WALL_THICKNESS,-WALL_THICKNESS])
		union(){
			cube(size = [length*BRICK_WIDTH-2*WALL_THICKNESS,width*BRICK_WIDTH-2*WALL_THICKNESS,height*PLATE_HEIGHT]);
			// stud inner holes, radius = pin radius
			if (!smooth) {

			}
			// small bottom line edge for smooth bricks
			else {
				translate([-WALL_THICKNESS-CORRECTION,-WALL_THICKNESS-CORRECTION,FLU-CORRECTION])
				difference() {
					cube([length*BRICK_WIDTH+2*CORRECTION,width*BRICK_WIDTH+2*CORRECTION,EDGE+CORRECTION]);
					translate([EDGE+CORRECTION,EDGE+CORRECTION,-CORRECTION])
					cube([length*BRICK_WIDTH-2*EDGE,width*BRICK_WIDTH-2*EDGE,EDGE+3*CORRECTION]);
				}
			}
		}
	}
	// Studs
	if(!smooth){
		translate([STUD_RADIUS+WALL_THICKNESS,STUD_RADIUS+WALL_THICKNESS,height*PLATE_HEIGHT])
		for (y = [0:width-1]){
			for (x = [0:length-1]){
				translate ([x*BRICK_WIDTH,y*BRICK_WIDTH,-CORRECTION])
				difference(){
					cylinder(h=STUD_HEIGHT+CORRECTION, r=STUD_RADIUS);
					// Stud inner holes
					translate([0,0,-CORRECTION])
					cylinder(h=0.5*STUD_HEIGHT+CORRECTION,r=PIN_RADIUS);
				}
				// tech logo - disable this if your printer isn't capable of printing this small
				if ( length > width){
					translate([x*BRICK_WIDTH+0.8,y*BRICK_WIDTH-1.9,STUD_HEIGHT-CORRECTION])
					resize([1.2*1.7,2.2*1.7,0.254+CORRECTION])
					rotate(a=[0,0,90])
					import("tech.stl");
				}
				else {
					translate([x*BRICK_WIDTH-1.9,y*BRICK_WIDTH-0.8,STUD_HEIGHT-CORRECTION])
					resize([2.2*1.7,1.2*1.7,0.254+CORRECTION])
					import("tech.stl");
				}
				/*
				// Alternative 2-square logo
				translate ([x*BRICK_WIDTH+CORRECTION,y*BRICK_WIDTH-CORRECTION,STUD_HEIGHT-CORRECTION])
				cube([1,1,2*CORRECTION]);
				translate ([x*BRICK_WIDTH-0.9,y*BRICK_WIDTH-0.9,STUD_HEIGHT-CORRECTION])
				cube([1,1,0.3]);
				*/
			}
		}
	}
	// Pins x
	if (width == 1 && length > 1) {
			for (x = [1:length-1]){
				translate([x*BRICK_WIDTH,0.5*BRICK_WIDTH,0])
				cylinder(h=height*PLATE_HEIGHT-WALL_THICKNESS+CORRECTION,r=PIN_RADIUS);
				// Supports
				if (height > 1) {
				translate([x*BRICK_WIDTH-0.5*SUPPORT_THICKNESS,CORRECTION,STUD_HEIGHT])
				cube(size=[SUPPORT_THICKNESS,BRICK_WIDTH-2*CORRECTION,height*PLATE_HEIGHT-STUD_HEIGHT-WALL_THICKNESS+CORRECTION]);
			}
		}
	}
	// Pins y
	if (length == 1 && width > 1) {
			for (y = [1:width-1]){
			translate([0.5*BRICK_WIDTH,y*BRICK_WIDTH,0])
			cylinder(h=height*PLATE_HEIGHT-WALL_THICKNESS+CORRECTION,r=PIN_RADIUS);
			// Supports
			if (height > 1) {
			translate([CORRECTION,y*BRICK_WIDTH-0.5*SUPPORT_THICKNESS,STUD_HEIGHT])
			cube(size=[BRICK_WIDTH-2*CORRECTION,SUPPORT_THICKNESS,height*PLATE_HEIGHT-STUD_HEIGHT-WALL_THICKNESS+CORRECTION]);}

		}
	}
	// Anti Studs
	if (width > 1 && length > 1){
		difference(){
			union(){
				for(y = [1:width-1]){
					for(x = [1:length-1]){
						// anti studs
						translate([x*BRICK_WIDTH,y*BRICK_WIDTH,0])
						cylinder (h=height*PLATE_HEIGHT-WALL_THICKNESS+CORRECTION, r = ANTI_STUD_RADIUS);
						// Supports
						if (height > 1){
							// Support x
							if (x%2 == 0 && (length%2 == 0 || length%4 == 1 && x<length/2 || length%4 == 3 && x>length/2) || x%2 == 1 && (length%4 == 3 && x<length/2 || length%4 == 1 && x>length/2)) {
								translate([BRICK_WIDTH*x-0.5*SUPPORT_THICKNESS,y*BRICK_WIDTH-BRICK_WIDTH+WALL_THICKNESS-CORRECTION,STUD_HEIGHT])
								cube(size=[SUPPORT_THICKNESS,2*BRICK_WIDTH-2*WALL_THICKNESS,height*PLATE_HEIGHT-STUD_HEIGHT-WALL_THICKNESS+CORRECTION]);
							}
							// Supports y
							if (y%2 == 0 && (width%2 == 0 || width%4 == 1 && y<width/2 || width%4 == 3 && y>width/2) || y%2 == 1 && (width%4 == 3 && y<width/2 || width%4 == 1 && y>width/2)) {
								translate([x*BRICK_WIDTH-BRICK_WIDTH+WALL_THICKNESS-CORRECTION,BRICK_WIDTH*y-0.5*SUPPORT_THICKNESS,STUD_HEIGHT])
								cube(size=[2*BRICK_WIDTH-2*WALL_THICKNESS,SUPPORT_THICKNESS,height*PLATE_HEIGHT-STUD_HEIGHT-WALL_THICKNESS+CORRECTION]);
							}
						}
					}
				}
			}
			union(){
				for(y = [1:width-1]){
					for(x = [1:length-1]){
						// hollow anti studs
						translate([x*BRICK_WIDTH,y*BRICK_WIDTH,-WALL_THICKNESS])
						cylinder (h=height*PLATE_HEIGHT, r = STUD_RADIUS);
					}
				}
			}
		}
	}
}

error: pathspec 'Modules/Action/Rotator/LegoShaft/DummyLegoBrick.scad' did not match any file(s) known to git


lower tub made thicker, so that it prints better; strucutre details simplified to build faster

/*
 * configuration
 */
brushes_count = 2;
//$fn=200;

/*
 * modules
 */

module lower_tub()
{
  translate([0, (20+4)/2, 0])
    difference()
    {
      cylinder(h=10+3, r=(20+3)/2);
      translate([0,0,3])
        cylinder(h=10+3, r2=20/2, r1=16/2);
    }
}

module upper_ring()
{
  translate([0, (24+5)/2, 0])
    difference()
    {
      cylinder(h=10, r=(24+5)/2);
      cylinder(h=10, r=(24+0)/2);
    }
}

module back_wall()
{
  // lower part
  translate([-40/2, 0, 0])
    cube([40, 3, 20]);
  // upper part
  translate([-40/2, 0, 100-10])
    cube([40, 3, 20]);
  // connector
  translate([-10/2, 0, 0])
    cube([10, 3, 100]);
}

module brush_holder()
{
  lower_tub();
  translate([0,0,100-5])
    upper_ring();
  back_wall();
  // lower mounting
  difference()
  {
    translate([-15/2, 3, 0])
      cube([15, 4, 10+3]);
    translate([0, 0.1, 0]) // needed to make model simple (aka: manifold)
      hull()
        lower_tub();
  }
  // upper mounting
  translate([0, 0, 100-5])
  {
    difference()
    {
      translate([-25/2, 3, 0])
        cube([25, 10, 10]);
      translate([0, 0.1, 0]) // needed to make model simple (aka: manifold)
        hull()
          upper_ring();
    }
  }
}

/*
 * main program
 */

rotate([90, 0, 0])
{
  for(offset = [0:brushes_count-1])
  {
    translate(offset * [30, 0, 0])
      brush_holder();
  }
}

/*
 * configuration
 */
brushes_count = 2;
$fn=200;

/*
 * modules
 */

module lower_tub()
{
  translate([0, (20+4)/2, 0])
    difference()
    {
      cylinder(h=10+3, r=20/2);
      translate([0,0,3])
        cylinder(h=10+3, r2=20/2, r1=16/2);
    }
}

module upper_ring()
{
  translate([0, (24+5)/2, 0])
    difference()
    {
      cylinder(h=10, r=(24+5)/2);
      cylinder(h=10, r=(24+0)/2);
    }
}

module back_wall()
{
  // lower part
  translate([-40/2, 0, 0])
    cube([40, 3, 20]);
  // upper part
  translate([-40/2, 0, 100-10])
    cube([40, 3, 20]);
  // connector
  translate([-10/2, 0, 0])
    cube([10, 3, 100]);
}

module brush_holder()
{
  lower_tub();
  translate([0,0,100-5])
    upper_ring();
  back_wall();
  // lower mounting
  difference()
  {
    translate([-15/2, 3, 0])
      cube([15, 4, 10+3]);
    translate([0, 0.1, 0]) // needed to make model simple (aka: manifold)
      hull()
        lower_tub();
  }
  // upper mounting
  translate([0, 0, 100-5])
  {
    difference()
    {
      translate([-25/2, 3, 0])
        cube([25, 10, 10]);
      translate([0, 0.1, 0]) // needed to make model simple (aka: manifold)
        hull()
          upper_ring();
    }
  }
}

/*
 * main program
 */

rotate([90, 0, 0])
{
  for(offset = [0:brushes_count-1])
  {
    translate(offset * [30, 0, 0])
      brush_holder();
  }
}


set LCD support dimensions

set LCD support dimensions

$fn = 20;
eps = 1e-3;

// TODO: Proper dimensions.
size_x = 80;
size_y = 36;
size_z = 11;
width = 4;

pin_length = 3;
pin_radius = 1.5;
pin_offset_left = 2.5;
pin_offset_right = pin_offset_left;
pin_offset_top = 2.5;
pin_offset_bottom = pin_offset_top;

translate([-size_x/2, 0, 0]) {
  cube([size_x, width, size_z]);
  cube([width, size_y, size_z]);
  translate([size_x - width, 0, 0]) {
    cube([width, size_y, size_z]);
  };
  translate([pin_offset_left, pin_offset_bottom, -pin_length]) {
    cylinder(2*pin_length + size_z, pin_radius);
  }
  translate([size_x - pin_offset_right, pin_offset_bottom, -pin_length]) {
    cylinder(2*pin_length + size_z, pin_radius);
  }
  translate([pin_offset_left, size_y - pin_offset_top, -pin_length]) {
    cylinder(2*pin_length + size_z, pin_radius);
  }
  translate([size_x - pin_offset_right, size_y - pin_offset_top, -pin_length]) {
    cylinder(2*pin_length + size_z, pin_radius);
  }
}

$fn = 20;
eps = 1e-3;

// TODO: Proper dimensions.
size_x = 50;
size_y = 20;
size_z = 7;
width = 4;

pin_length = 3;
pin_radius = 1;
pin_offset_left = 2;
pin_offset_right = pin_offset_left;
pin_offset_top = 2;
pin_offset_bottom = 2;

translate([-size_x/2, 0, 0]) {
  cube([size_x, width, size_z]);
  cube([width, size_y, size_z]);
  translate([size_x - width, 0, 0]) {
    cube([width, size_y, size_z]);
  };
  translate([pin_offset_left, pin_offset_bottom, -pin_length]) {
    cylinder(pin_length + eps, pin_radius);
  }
  translate([size_x - pin_offset_right, pin_offset_bottom, -pin_length]) {
    cylinder(pin_length + eps, pin_radius);
  }
  translate([pin_offset_left, size_y - pin_offset_top, -pin_length]) {
    cylinder(pin_length + eps, pin_radius);
  }
  translate([size_x - pin_offset_right, size_y - pin_offset_top, -pin_length]) {
    cylinder(pin_length + eps, pin_radius);
  }
}


nipple_module

HEIGHT_BODY = 44.5;
DIAMETER_BODY = 10.4;
BORDER_RADIUS_BODY = 0.2;

DIAMETER_BASE = 6;
BORDER_RADIUS_BASE = 0.3;

HEIGHT_NIPPLE = 0.8;
DIAMETER_NIPPLE = 3;
BORDER_NIPPLE = 0.2;
DIAMETER_BASE_NIPPLE = 6;

GREY = "LightGrey";

module nipple()
{
    color(GREY)
        translate([0,0,-BORDER_NIPPLE])
            cylinder(
                h = BORDER_NIPPLE,
                d = (DIAMETER_NIPPLE - (2 * BORDER_NIPPLE)),
                $fn = 100);

    //First shoulder
color(GREY)
translate([0,0,-BORDER_NIPPLE])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_NIPPLE/2)-BORDER_NIPPLE, 0, 0])
        circle(r = BORDER_NIPPLE, $fn = 100);

//Main nipple cylinder
color(GREY)
translate([0,0,-(HEIGHT_NIPPLE - BORDER_NIPPLE)])
    cylinder(
        h = (HEIGHT_NIPPLE - (BORDER_NIPPLE + BORDER_NIPPLE)),
        d = DIAMETER_NIPPLE,
        $fn = 100);

//Main nipple cylinder; base fillet
color(GREY)
difference()
{
    translate([0,0,BORDER_NIPPLE - HEIGHT_NIPPLE])
        rotate_extrude(convexity = 10, $fn = 100)
        translate([(DIAMETER_NIPPLE/2), 0, 0])
            square((BORDER_NIPPLE),(BORDER_NIPPLE));

    translate([0,0,(2 * BORDER_NIPPLE) - HEIGHT_NIPPLE])
        rotate_extrude(convexity = 10, $fn = 100)
        translate([(DIAMETER_NIPPLE/2)+ BORDER_NIPPLE, 0, 0])
            circle(r = BORDER_NIPPLE, $fn = 100);
}

//Nipple shoulder cylinder
color(GREY)
translate([0,0,-HEIGHT_NIPPLE])
    cylinder(
        h = BORDER_NIPPLE,
        d = DIAMETER_BASE_NIPPLE - (2 * BORDER_NIPPLE),
        $fn = 100);

//Nipple base shoulder
color(GREY)
translate([0,0,-HEIGHT_NIPPLE])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_BASE_NIPPLE/2)-BORDER_NIPPLE, 0, 0])
        circle(r = BORDER_NIPPLE, $fn = 100);

}

module RenderCell()
{
//Top face of main body
translate([0,0,-(HEIGHT_NIPPLE + BORDER_RADIUS_BODY)])
    cylinder(
        h = BORDER_RADIUS_BODY,
        d = (DIAMETER_BODY - (2 * BORDER_RADIUS_BODY)),
        $fn = 100);

//Body top shoulder
translate([0,0,-(HEIGHT_NIPPLE + BORDER_RADIUS_BODY)])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_BODY/2)-BORDER_RADIUS_BODY, 0, 0])
        circle(r = BORDER_RADIUS_BODY, $fn = 100);

//Main body cylinder
translate([0,0,-(HEIGHT_BODY - BORDER_RADIUS_BODY)])
    cylinder(
        h = (HEIGHT_BODY - (HEIGHT_NIPPLE + (2* BORDER_RADIUS_BODY))),
        d = DIAMETER_BODY,
        $fn = 100);

//Body bottom shoulder
translate([0,0,-(HEIGHT_BODY - BORDER_RADIUS_BODY)])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_BODY/2)-BORDER_RADIUS_BODY, 0, 0])
        circle(r = BORDER_RADIUS_BODY, $fn = 100);

//Bottom face of body
translate([0,0,-(HEIGHT_BODY)])
    cylinder(
        h = BORDER_RADIUS_BODY,
        d = (DIAMETER_BODY - (2 * BORDER_RADIUS_BODY)),
        $fn = 100);

//Base cylinder
color(GREY)
translate([0,0,-(HEIGHT_BODY + BORDER_RADIUS_BASE)])
    cylinder(
        h = BORDER_RADIUS_BASE,
        d = (DIAMETER_BASE - (2 * BORDER_RADIUS_BASE)),
        $fn = 100);

//Base shoulder
color(GREY)
translate([0,0,-(HEIGHT_BODY)])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_BASE/2)-BORDER_RADIUS_BASE, 0, 0])
        circle(r = BORDER_RADIUS_BASE, $fn = 100);
}
nipple();
RenderCell();

HEIGHT_BODY = 44.5;
DIAMETER_BODY = 10.4;
BORDER_RADIUS_BODY = 0.2;

DIAMETER_BASE = 6;
BORDER_RADIUS_BASE = 0.3;

HEIGHT_NIPPLE = 0.8;
DIAMETER_NIPPLE = 3;
BORDER_NIPPLE = 0.2;
DIAMETER_BASE_NIPPLE = 6;

module RenderCell()
{
//Top face of nipple
color("LightGrey")
translate([0,0,-BORDER_NIPPLE])
    cylinder(
        h = BORDER_NIPPLE,
        d = (DIAMETER_NIPPLE - (2 * BORDER_NIPPLE)),
        $fn = 100);

//First shoulder
color("LightGrey")
translate([0,0,-BORDER_NIPPLE])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_NIPPLE/2)-BORDER_NIPPLE, 0, 0])
        circle(r = BORDER_NIPPLE, $fn = 100);

//Main nipple cylinder
color("LightGrey")
translate([0,0,-(HEIGHT_NIPPLE - BORDER_NIPPLE)])
    cylinder(
        h = (HEIGHT_NIPPLE - (BORDER_NIPPLE + BORDER_NIPPLE)),
        d = DIAMETER_NIPPLE,
        $fn = 100);

//Main nipple cylinder; base fillet
color("LightGrey")
difference()
{
    translate([0,0,BORDER_NIPPLE - HEIGHT_NIPPLE])
        rotate_extrude(convexity = 10, $fn = 100)
        translate([(DIAMETER_NIPPLE/2), 0, 0])
            square((BORDER_NIPPLE),(BORDER_NIPPLE));

    translate([0,0,(2 * BORDER_NIPPLE) - HEIGHT_NIPPLE])
        rotate_extrude(convexity = 10, $fn = 100)
        translate([(DIAMETER_NIPPLE/2)+ BORDER_NIPPLE, 0, 0])
            circle(r = BORDER_NIPPLE, $fn = 100);
}

//Nipple shoulder cylinder
color("LightGrey")
translate([0,0,-HEIGHT_NIPPLE])
    cylinder(
        h = BORDER_NIPPLE,
        d = DIAMETER_BASE_NIPPLE - (2 * BORDER_NIPPLE),
        $fn = 100);

//Nipple base shoulder
color("LightGrey")
translate([0,0,-HEIGHT_NIPPLE])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_BASE_NIPPLE/2)-BORDER_NIPPLE, 0, 0])
        circle(r = BORDER_NIPPLE, $fn = 100);

//Top face of main body
translate([0,0,-(HEIGHT_NIPPLE + BORDER_RADIUS_BODY)])
    cylinder(
        h = BORDER_RADIUS_BODY,
        d = (DIAMETER_BODY - (2 * BORDER_RADIUS_BODY)),
        $fn = 100);

//Body top shoulder
translate([0,0,-(HEIGHT_NIPPLE + BORDER_RADIUS_BODY)])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_BODY/2)-BORDER_RADIUS_BODY, 0, 0])
        circle(r = BORDER_RADIUS_BODY, $fn = 100);

//Main body cylinder
translate([0,0,-(HEIGHT_BODY - BORDER_RADIUS_BODY)])
    cylinder(
        h = (HEIGHT_BODY - (HEIGHT_NIPPLE + (2* BORDER_RADIUS_BODY))),
        d = DIAMETER_BODY,
        $fn = 100);

//Body bottom shoulder
translate([0,0,-(HEIGHT_BODY - BORDER_RADIUS_BODY)])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_BODY/2)-BORDER_RADIUS_BODY, 0, 0])
        circle(r = BORDER_RADIUS_BODY, $fn = 100);

//Bottom face of body
translate([0,0,-(HEIGHT_BODY)])
    cylinder(
        h = BORDER_RADIUS_BODY,
        d = (DIAMETER_BODY - (2 * BORDER_RADIUS_BODY)),
        $fn = 100);

//Base cylinder
color("LightGrey")
translate([0,0,-(HEIGHT_BODY + BORDER_RADIUS_BASE)])
    cylinder(
        h = BORDER_RADIUS_BASE,
        d = (DIAMETER_BASE - (2 * BORDER_RADIUS_BASE)),
        $fn = 100);

//Base shoulder
color("LightGrey")
translate([0,0,-(HEIGHT_BODY)])
    rotate_extrude(convexity = 10, $fn = 100)
    translate([(DIAMETER_BASE/2)-BORDER_RADIUS_BASE, 0, 0])
        circle(r = BORDER_RADIUS_BASE, $fn = 100);
}
RenderCell();


minor change

minor change

/*
	roundedCube() v1.0.0 by robert@cosmicrealms.com from https://github.com/Sembiance/openscad-modules
	Allows you to round any edge of a cube

	Usage
	=====
	Prototype: roundedCube(dim, r, x, y, z, xcorners, ycorners, zcorners, $fn)
	Arguments:
		-      dim = Array of x,y,z numbers representing cube size
		-        r = Radius of corners. Default: 1
		-        x = Round the corners along the X axis of the cube. Default: false
		-        y = Round the corners along the Y axis of the cube. Default: false
		-        z = Round the corners along the Z axis of the cube. Default: true
		- xcorners = Array of 4 booleans, one for each X side of the cube, if true then round that side. Default: [true, true, true, true]
		- ycorners = Array of 4 booleans, one for each Y side of the cube, if true then round that side. Default: [true, true, true, true]
		- zcorners = Array of 4 booleans, one for each Z side of the cube, if true then round that side. Default: [true, true, true, true]
		-   center = Whether to render the cube centered or not. Default: false
		-      $fn = How smooth you want the rounding to be. Default: 128

	Change Log
	==========
	2017-05-15: v1.0.2 - Fixed bugs relating to rounding corners on the X axis
	2017-04-22: v1.0.1 - Added center option
	2017-01-04: v1.0.0 - Initial Release

	Thanks to Sergio Vilches for the initial code inspiration
*/

// Example code:

/*cube([5, 10, 4]);

translate([8, 0, 0]) { roundedCube([5, 10, 4], r=1); }
translate([16, 0, 0]) { roundedCube([5, 10, 4], r=1, zcorners=[true, false, true, false]); }

translate([24, 0, 0]) { roundedCube([5, 10, 4], r=1, y=true, z=false); }
translate([32, 0, 0]) { roundedCube([5, 10, 4], r=1, x=true, z=false); }
translate([40, 0, 0]) { roundedCube([5, 10, 4], r=1, x=true, y=true, z=true); }
*/

module roundedCube(dim, r=1, x=false, y=false, z=true, xcorners=[true,true,true,true], ycorners=[true,true,true,true], zcorners=[true,true,true,true], center=false, $fn=128)
{
	translate([(center==true ? (-(dim[0]/2)) : 0), (center==true ? (-(dim[1]/2)) : 0), (center==true ? (-(dim[2]/2)) : 0)])
	{
		difference()
		{
			cube(dim);

			if(z)
			{
				translate([0, 0, -0.1])
				{
					if(zcorners[0])
						translate([0, dim[1]-r]) { rotateAround([0, 0, 90], [r/2, r/2, 0]) { meniscus(h=dim[2], r=r, fn=$fn); } }
					if(zcorners[1])
						translate([dim[0]-r, dim[1]-r]) { meniscus(h=dim[2], r=r, fn=$fn); }
					if(zcorners[2])
						translate([dim[0]-r, 0]) { rotateAround([0, 0, -90], [r/2, r/2, 0]) { meniscus(h=dim[2], r=r, fn=$fn); } }
					if(zcorners[3])
						rotateAround([0, 0, -180], [r/2, r/2, 0]) { meniscus(h=dim[2], r=r, fn=$fn); }
				}
			}

			if(y)
			{
				translate([0, -0.1, 0])
				{
					if(ycorners[0])
						translate([0, 0, dim[2]-r]) { rotateAround([0, 180, 0], [r/2, 0, r/2]) { rotateAround([-90, 0, 0], [0, r/2, r/2]) { meniscus(h=dim[1], r=r); } } }
					if(ycorners[1])
						translate([dim[0]-r, 0, dim[2]-r]) { rotateAround([0, -90, 0], [r/2, 0, r/2]) { rotateAround([-90, 0, 0], [0, r/2, r/2]) { meniscus(h=dim[1], r=r); } } }
					if(ycorners[2])
						translate([dim[0]-r, 0]) { rotateAround([-90, 0, 0], [0, r/2, r/2]) { meniscus(h=dim[1], r=r); } }
					if(ycorners[3])
						rotateAround([0, 90, 0], [r/2, 0, r/2]) { rotateAround([-90, 0, 0], [0, r/2, r/2]) { meniscus(h=dim[1], r=r); } }
				}
			}

			if(x)
			{
				translate([-0.1, 0, 0])
				{
					if(xcorners[0])
						translate([0, dim[1]-r]) { rotateAround([0, 90, 0], [r/2, 0, r/2]) { meniscus(h=dim[0], r=r); } }
					if(xcorners[1])
						translate([0, dim[1]-r, dim[2]-r]) { rotateAround([90, 0, 0], [0, r/2, r/2]) { rotateAround([0, 90, 0], [r/2, 0, r/2]) { meniscus(h=dim[0], r=r); } } }
					if(xcorners[2])
						translate([0, 0, dim[2]-r]) { rotateAround([180, 0, 0], [0, r/2, r/2]) { rotateAround([0, 90, 0], [r/2, 0, r/2]) { meniscus(h=dim[0], r=r); } } }
					if(xcorners[3])
						rotateAround([-90, 0, 0], [0, r/2, r/2]) { rotateAround([0, 90, 0], [r/2, 0, r/2]) { meniscus(h=dim[0], r=r); } }
				}
			}
		}
	}
}

module meniscus(h, r, fn=128)
{
	$fn=fn;

	difference()
	{
		cube([r+0.2, r+0.2, h+0.2]);
		translate([0, 0, -0.1]) { cylinder(h=h+0.4, r=r); }
	}
}

module rotateAround(a, v) { translate(v) { rotate(a) { translate(-v) { children(); } } } }

/*
	roundedCube() v1.0.0 by robert@cosmicrealms.com from https://github.com/Sembiance/openscad-modules
	Allows you to round any edge of a cube

	Usage
	=====
	Prototype: roundedCube(dim, r, x, y, z, xcorners, ycorners, zcorners, $fn)
	Arguments:
		-      dim = Array of x,y,z numbers representing cube size
		-        r = Radius of corners. Default: 1
		-        x = Round the corners along the X axis of the cube. Default: false
		-        y = Round the corners along the Y axis of the cube. Default: false
		-        z = Round the corners along the Z axis of the cube. Default: true
		- xcorners = Array of 4 booleans, one for each X side of the cube, if true then round that side. Default: [true, true, true, true]
		- ycorners = Array of 4 booleans, one for each Y side of the cube, if true then round that side. Default: [true, true, true, true]
		- zcorners = Array of 4 booleans, one for each Z side of the cube, if true then round that side. Default: [true, true, true, true]
		-   center = Whether to render the cube centered or not. Default: false
		-      $fn = How smooth you want the rounding to be. Default: 128

	Change Log
	==========
	2017-05-15: v1.0.2 - Fixed bugs relating to rounding corners on the X axis
	2017-04-22: v1.0.1 - Added center option
	2017-01-04: v1.0.0 - Initial Release

	Thanks to Sergio Vilches for the initial code inspiration
*/

// Example code:
/*
cube([5, 10, 4]);

translate([8, 0, 0]) { roundedCube([5, 10, 4], r=1); }
translate([16, 0, 0]) { roundedCube([5, 10, 4], r=1, zcorners=[true, false, true, false]); }

translate([24, 0, 0]) { roundedCube([5, 10, 4], r=1, y=true, z=false); }
translate([32, 0, 0]) { roundedCube([5, 10, 4], r=1, x=true, z=false); }
translate([40, 0, 0]) { roundedCube([5, 10, 4], r=1, x=true, y=true, z=true); }
*/

module roundedCube(dim, r=1, x=false, y=false, z=true, xcorners=[true,true,true,true], ycorners=[true,true,true,true], zcorners=[true,true,true,true], center=false, $fn=128)
{
	translate([(center==true ? (-(dim[0]/2)) : 0), (center==true ? (-(dim[1]/2)) : 0), (center==true ? (-(dim[2]/2)) : 0)])
	{
		difference()
		{
			cube(dim);

			if(z)
			{
				translate([0, 0, -0.1])
				{
					if(zcorners[0])
						translate([0, dim[1]-r]) { rotateAround([0, 0, 90], [r/2, r/2, 0]) { meniscus(h=dim[2], r=r, fn=$fn); } }
					if(zcorners[1])
						translate([dim[0]-r, dim[1]-r]) { meniscus(h=dim[2], r=r, fn=$fn); }
					if(zcorners[2])
						translate([dim[0]-r, 0]) { rotateAround([0, 0, -90], [r/2, r/2, 0]) { meniscus(h=dim[2], r=r, fn=$fn); } }
					if(zcorners[3])
						rotateAround([0, 0, -180], [r/2, r/2, 0]) { meniscus(h=dim[2], r=r, fn=$fn); }
				}
			}

			if(y)
			{
				translate([0, -0.1, 0])
				{
					if(ycorners[0])
						translate([0, 0, dim[2]-r]) { rotateAround([0, 180, 0], [r/2, 0, r/2]) { rotateAround([-90, 0, 0], [0, r/2, r/2]) { meniscus(h=dim[1], r=r); } } }
					if(ycorners[1])
						translate([dim[0]-r, 0, dim[2]-r]) { rotateAround([0, -90, 0], [r/2, 0, r/2]) { rotateAround([-90, 0, 0], [0, r/2, r/2]) { meniscus(h=dim[1], r=r); } } }
					if(ycorners[2])
						translate([dim[0]-r, 0]) { rotateAround([-90, 0, 0], [0, r/2, r/2]) { meniscus(h=dim[1], r=r); } }
					if(ycorners[3])
						rotateAround([0, 90, 0], [r/2, 0, r/2]) { rotateAround([-90, 0, 0], [0, r/2, r/2]) { meniscus(h=dim[1], r=r); } }
				}
			}

			if(x)
			{
				translate([-0.1, 0, 0])
				{
					if(xcorners[0])
						translate([0, dim[1]-r]) { rotateAround([0, 90, 0], [r/2, 0, r/2]) { meniscus(h=dim[0], r=r); } }
					if(xcorners[1])
						translate([0, dim[1]-r, dim[2]-r]) { rotateAround([90, 0, 0], [0, r/2, r/2]) { rotateAround([0, 90, 0], [r/2, 0, r/2]) { meniscus(h=dim[0], r=r); } } }
					if(xcorners[2])
						translate([0, 0, dim[2]-r]) { rotateAround([180, 0, 0], [0, r/2, r/2]) { rotateAround([0, 90, 0], [r/2, 0, r/2]) { meniscus(h=dim[0], r=r); } } }
					if(xcorners[3])
						rotateAround([-90, 0, 0], [0, r/2, r/2]) { rotateAround([0, 90, 0], [r/2, 0, r/2]) { meniscus(h=dim[0], r=r); } }
				}
			}
		}
	}
}

module meniscus(h, r, fn=128)
{
	$fn=fn;

	difference()
	{
		cube([r+0.2, r+0.2, h+0.2]);
		translate([0, 0, -0.1]) { cylinder(h=h+0.4, r=r); }
	}
}

module rotateAround(a, v) { translate(v) { rotate(a) { translate(-v) { children(); } } } }


main: Centex x carriage again

main: Centex x carriage again

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>

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

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,axis_pos_z])
    {
        translate([axis_pos_x,0,0])
        {
            xaxis_bearing_dist = 10;
            xcarriage_padding=10;
            xcarriage_width = xaxis_bearing[2]*2 + xaxis_bearing_dist + xcarriage_padding;
            // x carriage
            translate([0,xaxis_zaxis_distance_y,0])
            translate([0,-xaxis_bearing[1]/2,0])
            cubea([xcarriage_width, 5, xaxis_rod_distance+xaxis_bearing[1]+xcarriage_padding], align=[0,-1,0]);

            attach([[-motor_offset_x-motorWidth(extruder_motor)/2, 10, -17], [0,0,0]], extruder_conn_xcarriage)
            /*#cubea([10,10,10]);*/
                extruder();

            // x carriage bearings
            for(j=[-1,1])
            translate([j*(xaxis_bearing_dist+xaxis_bearing[2])/2,xaxis_zaxis_distance_y,(xaxis_rod_distance/2)])
                bearing(xaxis_bearing, orient=[1,0,0]);

            translate([0, xaxis_zaxis_distance_y, -(xaxis_rod_distance/2)])
                bearing(xaxis_bearing, orient=[1,0,0]);
        }

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

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

            for(j=[-1,1])
                translate([0,j*(yaxis_rod_distance/2),0])
                    bearing(yaxis_bearing, orient=[0,1,0]);
        }

        translate([0,0,yaxis_bearing[1]/2])
        {
            // y axis plate
            cubea(ycarriage_size, align=[0,0,1]);
        }
    }

    // z axis
    for(i=[-1,1])
    translate([i*(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
    {
        translate([0,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+zmotor_mount_motor_offset),0,0])
        {
            translate([0,0,zaxis_motor_offset_z])
                fncylindera(h=zaxis_rod_l,d=zaxis_rod_d,align=[0,0,1]);

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

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

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])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia, orient=[1,0,0]);
    }

    // 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])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
    }

/*#    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>
use <thing_libutils/linear-extrusion.scad>;

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

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

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

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,axis_pos_z])
    {
        translate([axis_pos_x,0,0])
        {
            xaxis_bearing_dist = 10;
            xcarriage_padding=10;
            xcarriage_width = xaxis_bearing[2]*2 + xaxis_bearing_dist + xcarriage_padding;
            // x carriage
            translate([0,xaxis_zaxis_distance_y,0])
            translate([0,-xaxis_bearing[1]/2,0])
            cubea([xcarriage_width, 5, xaxis_rod_distance+xaxis_bearing[1]+xcarriage_padding], align=[0,-1,0]);

            attach([[-motor_offset_x-motorWidth(extruder_motor)/2, 10, -17], [0,0,0]], extruder_conn_xcarriage)
            /*#cubea([10,10,10]);*/
                extruder();

            // x carriage bearings
            for(j=[-1,1])
            translate([j*(xaxis_bearing_dist+xaxis_bearing[2])/2,xaxis_zaxis_distance_y,(xaxis_rod_distance/2)])
                bearing(xaxis_bearing, orient=[1,0,0]);

            translate([0, xaxis_zaxis_distance_y, -(xaxis_rod_distance/2)])
                bearing(xaxis_bearing, orient=[1,0,0]);
        }

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

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

            for(j=[-1,1])
                translate([0,j*(yaxis_rod_distance/2),0])
                    bearing(yaxis_bearing, orient=[0,1,0]);
        }

        translate([0,0,yaxis_bearing[1]/2])
        {
            // y axis plate
            cubea(ycarriage_size, align=[0,0,1]);
        }
    }

    // z axis
    for(i=[-1,1])
    translate([i*(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
    {
        translate([0,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+zmotor_mount_motor_offset),0,0])
        {
            translate([0,0,zaxis_motor_offset_z])
                fncylindera(h=zaxis_rod_l,d=zaxis_rod_d,align=[0,0,1]);

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

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

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])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia, orient=[1,0,0]);
    }

    // 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])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
    }

/*#    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]);
}


psu: apply rounding

psu: apply rounding

include <psu.h>

use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;

module psu_a(align=N, detailed_model=true)
{
    if(detailed_model)
    {
        size_align([psu_a_w,psu_a_d,psu_a_h], align)
            translate([-24.5,105,-25])
            rotate([0,0,90])
            import("stl/ledpowersupply.stl");
    }
    else
    {
        size_align([psu_a_w,psu_a_d,psu_a_h], align)
        difference()
        {
            cubea([psu_a_w,psu_a_d,psu_a_h]);

            // screw holes, sides
            for(x=[-1,1])
                for(y=[-1,1])
                    for(z=[-1,1])
                        translate([x*(psu_a_w/2+1), y*(psu_a_screw_dist_y/2), z*psu_a_screw_side_dist_z/2])
                            rcylindera(d=psu_a_screw_thread_dia, h=0.5*cm, orient=X, align=[-x,0,0]);

            // screw holes, bottom
            for(x=[-1,1])
                for(y=[-1,1])
                    translate([x*(psu_a_screw_bottom_dist_x/2), y*(psu_a_screw_dist_y/2), -psu_a_h/2-1])
                        rcylindera(d=psu_a_screw_thread_dia, h=1*cm, orient=Z, align=Z);
        }
    }
}

module psu_a_extrusion_bracket_side()
{
    extrusion_side_screw_dist = 3*cm;
    difference()
    {
        hull()
        {
            for(x=[-1,1])
                translate([x*(psu_a_screw_bottom_dist_x/2), 0, -psu_a_h/2])
                    rcylindera(d=psu_a_screw_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);

            for(y=[-1,1])
                translate([psu_a_w/2+extrusion_size/2, y*extrusion_side_screw_dist/2, -psu_a_h/2])
                    rcylindera(d=extrusion_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);
        }

        for(x=[-1,1])
            translate([x*(psu_a_screw_bottom_dist_x/2), 0, -psu_a_h/2+1])
                rcylindera(d=psu_a_screw_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);

        for(y=[-1,1])
            translate([psu_a_w/2+extrusion_size/2, y*extrusion_side_screw_dist/2, -psu_a_h/2+1])
                rcylindera(d=extrusion_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);
    }
}

module psu_a_extrusion_bracket_back()
{
    extrusion_side_screw_dist = 3*cm;
    difference()
    {
        hull()
        {
            for(x=[-1,1])
                translate([x*(psu_a_screw_bottom_dist_x/2), 0, -psu_a_h/2])
                    rcylindera(d=psu_a_screw_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);

            for(x=[-1,1])
                translate([x*psu_a_screw_bottom_dist_x/2, -psu_a_screw_dist_y/2+psu_a_d/2+extrusion_size/2, -psu_a_h/2])
                    rcylindera(d=extrusion_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);
        }

        for(x=[-1,1])
            translate([x*(psu_a_screw_bottom_dist_x/2), 0, -psu_a_h/2+1])
                cylindera(d=psu_a_screw_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);

        for(x=[-1,1])
            translate([x*psu_a_screw_bottom_dist_x/2, -psu_a_screw_dist_y/2+psu_a_d/2+extrusion_size/2, -psu_a_h/2+1])
                cylindera(d=extrusion_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);
    }
}

module psu_b(align=N)
{
    {
        size_align([psu_b_w,psu_b_d,psu_b_h], align)
        difference()
        {
            rcubea([psu_b_w,psu_b_d,psu_b_h]);

            // screw holes, sides
            /*for(x=[-1,1])*/
                /*for(y=[-1,1])*/
                    /*for(z=[-1,1])*/
                        /*translate([x*(psu_b_w/2+1), y*(psu_b_screw_dist_y/2), z*psu_b_screw_side_dist_z/2])*/
                            /*cylindera(d=psu_b_screw_thread_dia, h=0.5*cm, orient=X, align=[-x,0,0]);*/

            // screw holes, bottom
            for(x=[-1,1])
                for(y=[-1,1])
                    translate([x*(psu_b_screw_bottom_dist_x/2), psu_b_screw_offset_y+y*(psu_b_screw_dist_y/2), -psu_b_h/2-1])
                        cylindera(d=psu_b_screw_thread_dia, h=1*cm, orient=Z, align=Z);
        }
    }
}

module psu_b_extrusion_bracket_side()
{
    extrusion_side_screw_dist = 3*cm;
    difference()
    {
        hull()
        {
            for(x=[-1,1])
                translate([x*(psu_b_screw_bottom_dist_x/2), 0, -psu_b_h/2])
                    rcylindera(d=psu_b_screw_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);

            for(y=[-1,1])
                translate([psu_b_w/2+extrusion_size/2, y*extrusion_side_screw_dist/2, -psu_b_h/2])
                    rcylindera(d=extrusion_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);
        }

        for(x=[-1,1])
            translate([x*(psu_b_screw_bottom_dist_x/2), 0, -psu_b_h/2+1])
                cylindera(d=psu_b_screw_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);

        for(y=[-1,1])
            translate([psu_b_w/2+extrusion_size/2, y*extrusion_side_screw_dist/2, -psu_b_h/2+1])
                cylindera(d=extrusion_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);
    }
}

module psu_b_extrusion_bracket_back()
{
    extrusion_side_screw_dist = 3*cm;
    difference()
    {
        hull()
        {
            for(x=[-1,1])
                translate([x*(psu_b_screw_bottom_dist_x/2), psu_b_screw_offset_y, -psu_b_h/2])
                    rcylindera(d=psu_b_screw_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);

            for(x=[-1,1])
                translate([x*psu_b_screw_bottom_dist_x/2, -psu_b_screw_dist_y/2+psu_b_d/2+extrusion_size/2, -psu_b_h/2])
                    rcylindera(d=extrusion_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);
        }

        for(x=[-1,1])
            translate([x*(psu_b_screw_bottom_dist_x/2), psu_b_screw_offset_y, -psu_b_h/2+1])
                cylindera(d=psu_b_screw_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);

        for(x=[-1,1])
            translate([x*psu_b_screw_bottom_dist_x/2, -psu_b_screw_dist_y/2+psu_b_d/2+extrusion_size/2, -psu_b_h/2+1])
                cylindera(d=extrusion_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);
    }
}

module part_psu_a_extrusion_bracket_side()
{
    psu_a_extrusion_bracket_side();
}

module part_psu_a_extrusion_bracket_back()
{
    psu_a_extrusion_bracket_back();
}

module part_psu_b_extrusion_bracket_side()
{
    psu_b_extrusion_bracket_side();
}

module part_psu_b_extrusion_bracket_back()
{
    psu_b_extrusion_bracket_back();
}

/*psu_a();*/

/*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();*/

/*psu_b();*/

/*translate([0, psu_b_screw_offset_y-psu_b_screw_dist_y/2, 0])*/
/*psu_b_extrusion_bracket_side();*/

/*translate([0, psu_b_screw_dist_y/2, 0])*/
/*psu_b_extrusion_bracket_back();*/

include <psu.h>

use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;

module psu_a(align=N, detailed_model=true)
{
    if(detailed_model)
    {
        size_align([psu_a_w,psu_a_d,psu_a_h], align)
            translate([-24.5,105,-25])
            rotate([0,0,90])
            import("stl/ledpowersupply.stl");
    }
    else
    {
        size_align([psu_a_w,psu_a_d,psu_a_h], align)
        difference()
        {
            cubea([psu_a_w,psu_a_d,psu_a_h]);

            // screw holes, sides
            for(x=[-1,1])
                for(y=[-1,1])
                    for(z=[-1,1])
                        translate([x*(psu_a_w/2+1), y*(psu_a_screw_dist_y/2), z*psu_a_screw_side_dist_z/2])
                            cylindera(d=psu_a_screw_thread_dia, h=0.5*cm, orient=X, align=[-x,0,0]);

            // screw holes, bottom
            for(x=[-1,1])
                for(y=[-1,1])
                    translate([x*(psu_a_screw_bottom_dist_x/2), y*(psu_a_screw_dist_y/2), -psu_a_h/2-1])
                        cylindera(d=psu_a_screw_thread_dia, h=1*cm, orient=Z, align=Z);
        }
    }
}

module psu_a_extrusion_bracket_side()
{
    extrusion_side_screw_dist = 3*cm;
    difference()
    {
        hull()
        {
            for(x=[-1,1])
                translate([x*(psu_a_screw_bottom_dist_x/2), 0, -psu_a_h/2])
                    cylindera(d=psu_a_screw_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);

            for(y=[-1,1])
                translate([psu_a_w/2+extrusion_size/2, y*extrusion_side_screw_dist/2, -psu_a_h/2])
                    cylindera(d=extrusion_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);
        }

        for(x=[-1,1])
            translate([x*(psu_a_screw_bottom_dist_x/2), 0, -psu_a_h/2+1])
                cylindera(d=psu_a_screw_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);

        for(y=[-1,1])
            translate([psu_a_w/2+extrusion_size/2, y*extrusion_side_screw_dist/2, -psu_a_h/2+1])
                cylindera(d=extrusion_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);
    }
}

module psu_a_extrusion_bracket_back()
{
    extrusion_side_screw_dist = 3*cm;
    difference()
    {
        hull()
        {
            for(x=[-1,1])
                translate([x*(psu_a_screw_bottom_dist_x/2), 0, -psu_a_h/2])
                    cylindera(d=psu_a_screw_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);

            for(x=[-1,1])
                translate([x*psu_a_screw_bottom_dist_x/2, -psu_a_screw_dist_y/2+psu_a_d/2+extrusion_size/2, -psu_a_h/2])
                    cylindera(d=extrusion_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);
        }

        for(x=[-1,1])
            translate([x*(psu_a_screw_bottom_dist_x/2), 0, -psu_a_h/2+1])
                cylindera(d=psu_a_screw_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);

        for(x=[-1,1])
            translate([x*psu_a_screw_bottom_dist_x/2, -psu_a_screw_dist_y/2+psu_a_d/2+extrusion_size/2, -psu_a_h/2+1])
                cylindera(d=extrusion_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);
    }
}

module psu_b(align=N)
{
    {
        size_align([psu_b_w,psu_b_d,psu_b_h], align)
        difference()
        {
            cubea([psu_b_w,psu_b_d,psu_b_h]);

            // screw holes, sides
            /*for(x=[-1,1])*/
                /*for(y=[-1,1])*/
                    /*for(z=[-1,1])*/
                        /*translate([x*(psu_b_w/2+1), y*(psu_b_screw_dist_y/2), z*psu_b_screw_side_dist_z/2])*/
                            /*cylindera(d=psu_b_screw_thread_dia, h=0.5*cm, orient=X, align=[-x,0,0]);*/

            // screw holes, bottom
            for(x=[-1,1])
                for(y=[-1,1])
                    translate([x*(psu_b_screw_bottom_dist_x/2), psu_b_screw_offset_y+y*(psu_b_screw_dist_y/2), -psu_b_h/2-1])
                        cylindera(d=psu_b_screw_thread_dia, h=1*cm, orient=Z, align=Z);
        }
    }
}

module psu_b_extrusion_bracket_side()
{
    extrusion_side_screw_dist = 3*cm;
    difference()
    {
        hull()
        {
            for(x=[-1,1])
                translate([x*(psu_b_screw_bottom_dist_x/2), 0, -psu_b_h/2])
                    cylindera(d=psu_b_screw_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);

            for(y=[-1,1])
                translate([psu_b_w/2+extrusion_size/2, y*extrusion_side_screw_dist/2, -psu_b_h/2])
                    cylindera(d=extrusion_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);
        }

        for(x=[-1,1])
            translate([x*(psu_b_screw_bottom_dist_x/2), 0, -psu_b_h/2+1])
                cylindera(d=psu_b_screw_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);

        for(y=[-1,1])
            translate([psu_b_w/2+extrusion_size/2, y*extrusion_side_screw_dist/2, -psu_b_h/2+1])
                cylindera(d=extrusion_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);
    }
}

module psu_b_extrusion_bracket_back()
{
    extrusion_side_screw_dist = 3*cm;
    difference()
    {
        hull()
        {
            for(x=[-1,1])
                translate([x*(psu_b_screw_bottom_dist_x/2), psu_b_screw_offset_y, -psu_b_h/2])
                    cylindera(d=psu_b_screw_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);

            for(x=[-1,1])
                translate([x*psu_b_screw_bottom_dist_x/2, -psu_b_screw_dist_y/2+psu_b_d/2+extrusion_size/2, -psu_b_h/2])
                    cylindera(d=extrusion_thread_dia*3, h=psu_mount_bottom_height, align=[0,0,-1]);
        }

        for(x=[-1,1])
            translate([x*(psu_b_screw_bottom_dist_x/2), psu_b_screw_offset_y, -psu_b_h/2+1])
                cylindera(d=psu_b_screw_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);

        for(x=[-1,1])
            translate([x*psu_b_screw_bottom_dist_x/2, -psu_b_screw_dist_y/2+psu_b_d/2+extrusion_size/2, -psu_b_h/2+1])
                cylindera(d=extrusion_thread_dia, h=psu_mount_bottom_height*2, align=[0,0,-1]);
    }
}

module part_psu_a_extrusion_bracket_side()
{
    psu_a_extrusion_bracket_side();
}

module part_psu_a_extrusion_bracket_back()
{
    psu_a_extrusion_bracket_back();
}

module part_psu_b_extrusion_bracket_side()
{
    psu_b_extrusion_bracket_side();
}

module part_psu_b_extrusion_bracket_back()
{
    psu_b_extrusion_bracket_back();
}

/*psu_a();*/

/*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();*/

/*psu_b();*/

/*translate([0, psu_b_screw_offset_y-psu_b_screw_dist_y/2, 0])*/
/*psu_b_extrusion_bracket_side();*/

/*translate([0, psu_b_screw_dist_y/2, 0])*/
/*psu_b_extrusion_bracket_back();*/


Create led-wire-guide.scad

Create led-wire-guide.scad

This is for keeping wires soldered to a "Super Bright 921 LED bulb" separated.

use <../common/extrusions.scad>
LARGE = 100;

// This is a wire guide for the "Super Bright 921 LED Bulbs" ordered for the CM Rig
// flash unit - to position and orient the power wires soldered to the tabs and keep
// them from moving and potentially shorting.
module wire_guide() {

    wb = 2; // Thickness of separator at it's narrowest (topmost part when oriented flat)
    hb = 4;
    wt = 9; // Width of the guide - side-to-side
    ht = 2;  // Thickness of thinnest portion of base of guide
    xoff = (wt - wb)/2;
    t = 7.5; // Length of base - front to back
    ri = 2; // Wire curvature
    ro = 0;

    T_channel(wb, hb, wt, ht, xoff, ro, ri, t);
}

wire_guide();

error: pathspec '3dprinting/openscad/led-wire-guide/led-wire-guide.scad' did not match any file(s) known to git


red pot's cover

red pot's cover

include <funcions.scad>;

int_dia=110;
ext_dia=129;

translate([0, ext_dia/2+15, 0])
  con();
lid(internal_diameter=int_dia, external_diameter=ext_dia);

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


work in progress checkpoint

work in progress checkpoint

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

// global rendering parameters
$fn = 24;

// 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 = .6;

// 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 = 200;
// misc
baseDeckExtension = 50;
// 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 = 120;

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

// shoulder base
color([.7, .7, 1])
    shoulderBase(shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// shoulder stepper
rotate([0, 180, 0])
    translate([-8, 0, 10])
        StepMotor28BYJ();
// lower shoulder bearing
translate([0, 0, shoulderBaseHeight + bearingStep])
    %bearing6807_2RS();
// shoulder - arm joint
render()
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);
// arm joint pieces
translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + bearingStep])
    %bearing6807_2RS();
// arm stepper
rotate([0, 180, 0])
    translate([armLength - 8, 0, bearingStep * 2])
        StepMotor28BYJ();
// forearm pieces
//render()
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);
/*
render()
    translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + (2* bearingStep)])
        armJointSpacer(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
*/

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

// 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(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));
    }
    // NOTE: need to add LM8UU mounts
}

module armLower(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength) {
    boundingBox = 12;
    boundingBoxHalf = boundingBox / 2;
    //
    armWidth = bearingOD + bearingStep;
    //render(convexivity = 3)
    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, 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 : armWidth / 2 : 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);
            }
        }
    }
   }
}

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

    union() {
        difference() {
            union() {
                translate([0, 0, -(bearingStep * 2)])
                    cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
                translate([0, 0, bearingStep * 2])
                    rotate([0, 180, 0])
                        bearingOuterStep(bearingOD, bearingStep, bearingStep);
            }
            // 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)])
    union() {
        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 holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - 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);
                    }
    }
}

module forearmLower(bearingID, bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength) {
    rotate([180, 0, 0]) union() {
        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);
    }
}

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

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

// global rendering parameters
$fn = 24;

// 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 = .6;

// 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 = 200;
// misc
baseDeckExtension = 50;
// 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;

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

// shoulder base
color([.7, .7, 1])
    shoulderBase(shoulderBaseHeight, shoulderBaseDiameter, shaftBossDiameter, mountScrewDiameter);
// shoulder stepper
rotate([0, 180, 0])
    translate([-8, 0, 10])
        StepMotor28BYJ();
// lower shoulder bearing
translate([0, 0, shoulderBaseHeight + bearingStep])
    %bearing6807_2RS();
// shoulder - arm joint
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);
// arm joint pieces
translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + bearingStep])
    %bearing6807_2RS();
// arm stepper
rotate([0, 180, 0])
    translate([armLength - 8, 0, bearingStep * 2])
        StepMotor28BYJ();
// forearm pieces
translate([-armLength, 0, 0])
    forearmLower(bearing6807_2RS_D - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingSteo, bearingStep, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength);
/*
render()
color([.1, .7, .1])
    translate([-armLength, 0, shoulderBaseHeight + bearing6807_2RS_B + (2* bearingStep)])
        armJointSpacer(bearing6807_2RS_d - iFitAdjust, bearing6807_2RS_D + iFitAdjust, bearingStep, shaftBossDiameter, mountScrewDiameter);
*/

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

// 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(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));
    }
    // NOTE: need to add LM8UU mounts
}

module armLower(bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, screwTabs, screwTabHeight, armLength) {
    boundingBox = 12;
    boundingBoxHalf = boundingBox / 2;
    //
    armWidth = bearingOD + bearingStep;
    //render(convexivity = 3)
    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, 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 : armWidth / 2 : 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);
            }
        }
    }
   }
}

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

    union() {
/*
        //render(convexivity = 3)
    difference() {
        cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
        cylinder(h = bearingStep * 2, d = bearingOD - 2 * bearingStep);
    }
         // screw holes for joining to joint
        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);
                    }
*/
        difference() {
            union() {
                translate([0, 0, -(bearingStep * 2)])
                    cylinder(h = bearingStep * 2, d = bearingOD + bearingStep);
                translate([0, 0, bearingStep * 2])
                    rotate([0, 180, 0])
                        bearingOuterStep(bearingOD, bearingStep, bearingStep);
            }
            // 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)])
    union() {
        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 holes for joining to upper
        radial_array(vec = [0, 0, 1], n = screwTabs)
                translate([bearingOD / 2 + (setScrewRadius * 2), 0, (2 * stepHeight) - 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);
                    }
    }
}

module forearmLower(bearingID, bearingOD, stepHeight, stepWidth, hubHeight, hubRadius, shaftHeight, shaftRadius, setScrewRadius, setScrewHeight, spokeWidth, spokes, forearmLength) {
}

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