Add documenation and refactor

Add documenation and refactor

//
//	Oregon Tech Print3D Rapid Prototyping Lab
//
//	Author: Dustin Kerns
//	Project: Wintermute Delta Printer
//	Purpose: To redefine base HIMAWARI travel bracket to suit the needs of the Wintermute fork
//

//
//	Generate model
//
TravelBracket();

//--------------------------------------------------------------------------------------------------------------------------------------

//
//	Module: NutSocket
//	Purpose: Defines the shape of a M3 Nut for screw mounts
//
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);
}

//
//	Module: Travel Bracket
//	Purpose: Revised Travel Bracket for Wintermute Delta Printer
//
module TravelBracket()
{

	standoff_height=1; // In mm

	difference()
	{
		// Fill in un-used aspects of base model and add new structure to the Travel Bracket
		union()
		{
			// Import base HIMAWIRI STL
			import("TRV_BRKT_V1_0.stl");

			// Fill in unneeded holes
			// These aspects of the original HIMAWRI base printer are not used on
			// the Wintermute fork
			translate([16,17,3])rotate([90,0,0])cylinder(h=10,r=1.8,$fn=40);
			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]);

			// Smooth out holes for linear bearings and generate standoff
			difference()
			{

				// Cylinder defining the outer shell
				union()
				{
					translate([25,0,0])cylinder(h=14+standoff_height,r=10,$fn=40);
					translate([-25,0,0])cylinder(h=14+standoff_height,r=10,$fn=40);
				}

				// Cylider defining the inner section to be removed
				// (Where the linear bearings will fit)
				union()
				{
					translate([25,0,-1])cylinder(h=18,r=8,$fn=40);
					translate([-25,0,-1])cylinder(h=18,r=8,$fn=40);
				}
			}
		}

		// Holes for set screws to add further support for linear bearings
		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);

		// Nut sockets for M3 set screws
		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);
	}
}

// Module containing code for revised Travel Bracket for Wintermute Delta Printer
module TravelBracket()
{
	difference()
	{
		union()
		{
			// Import base HIMAWIRI STL from approved directory
			import("..//..//approved//TRV_BRKT.stl");

			// Fill in unneeded holes
			// These aspects of the original HIMAWRI base printer are not used on
			// the Wintermute fork
			translate([16,17,3])rotate([90,0,0])cylinder(h=10,r=1.8,$fn=40);
			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()
			{
				// Cylinder defining the outer shell
				union()
				{
					translate([25,0,0])cylinder(h=16,r=10,$fn=40);	// Left
					translate([-25,0,0])cylinder(h=16,r=10,$fn=40);	// Right
				}

				// Cylider defining the inner section to be removed
				// (Where the linear bearings will fit)
				union()
				{
					translate([25,0,-1])cylinder(h=18,r=8,$fn=40);	// Left
					translate([-25,0,-1])cylinder(h=18,r=8,$fn=40);	// Right
				}
			}
		}
		// Holes for set screws to add further support for linear bearings
		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 defining the shape of a M3 Nut for screw mounts
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);
	}
}


The font name was updated.

The font name was updated.

/* [Base] */

// This parameter is all about that base color.
baseColor = "black"; // [pink, red, black, white, yellow, blue, green]

baseThickness = 2; // [1 : 5]

// This determines how wide the name tag is.
baseWidth = 228;	// [228:600]

// This determines the height of the name tag.
baseHeight = 15; // [54:150]

/* [Border] */
borderColor = "yellow"; // [pink, red, black, white, yellow, blue, green]
showBorder = "No"; // [Yes, No]

/* [Bottom Text] */
bottomText = "Fun Enthusiast";
bottomTextFont = "Wingdings";
bottomTextOffsetX = 0; // [-315 : 315]
bottomTextOffsetY = -20; // [-315 : 315]

/* [Chain Loop]*/
chainLoop = true;
chainLoopLengthZ = 6;
chainLoopPosition = "bottom"; // [bottom, top]

/* [General] */
letterThickness = 3; // [1 : 15]

/* [Icons] */
iconColor = "white"; // [pink, red, black, white, yellow, blue, green]
//TODO: Where is the heart icon, man?  "Put your heart into it."
leftIconType = "Moon";   // [Bass Clef, Creeper, Light Bulb, Moon, Rebel, Trooper, Aqua Dude, Cat, Fan, Spur, Mario, Luigi, Sun, Thundercat, Treble Clef]
rightIconType = "Sun";          // [Bass Clef, Creeper, Light Bulb, Moon, Rebel, Trooper, Aqua Dude, Cat, Fan, Spur, Mario, Luigi, Sun, Thundercat, Treble Clef]

// This is the x off set of the icons
xIconOffset = -100; // [10:200]

// This is the y off set of the icons
yIconOffset = 3;  // [1:200]

// This is the X,Y scale of the icons.
leftIconXyScale = 0.5;  // [0.1 : 0.05 : 5]

rightIconXyScale = 0.25; // [0.1 : 0.05 : 5]

leftIconHeight = 2.5; // [0.1: 0.1 :5]
rightIconHeight = 4.0; // [0.1: 0.1 :5]

/* [Top Text] */
topText = "Firstnesto Lastquez";
topTextColor = "white"; // [pink, red, black, white, yellow, blue, green]
topTextFont = "Arial";

/* [Hidden] */

use <../name-tag.scad>

nametag(baseColor = baseColor,
        baseThickness = baseThickness,
        borderColor = borderColor,
        chainLoop = chainLoop,
        chainLoopLengthZ = chainLoopLengthZ,
        chainLoopPosition = chainLoopPosition,
        iconColor = iconColor,
        letterThickness = letterThickness,
        roundedCorners = true,
        topText = topText,
        topTextSize = 13,
        topTextColor = topTextColor,
        topTextFont = topTextFont,
        bottomText = bottomText,
        bottomTextFont = bottomTextFont,
        bottomTextOffsetX = bottomTextOffsetX,
        bottomTextOffsetY = bottomTextOffsetY,
//        font=font,
        leftIconType = leftIconType,
        leftIconHeight = leftIconHeight,
        rightIconHeight = rightIconHeight,
//        rightIconOffsetY = 0,
        rightIconType = rightIconType,
        xIconOffset = xIconOffset,
        yIconOffset = yIconOffset,
        baseWidth = baseWidth,
        showBorder = showBorder);

/* [Base] */

// This parameter is all about that base color.
baseColor = "black"; // [pink, red, black, white, yellow, blue, green]

baseThickness = 2; // [1 : 5]

// This determines how wide the name tag is.
baseWidth = 228;	// [228:600]

// This determines the height of the name tag.
baseHeight = 15; // [54:150]

/* [Border] */
borderColor = "yellow"; // [pink, red, black, white, yellow, blue, green]
showBorder = "No"; // [Yes, No]

/* [Bottom Text] */
bottomText = "Fun Enthusiast";
bottomTextFont = "Wingdings";
bottomTextOffsetX = 0; // [-315 : 315]
bottomTextOffsetY = -20; // [-315 : 315]

/* [Chain Loop]*/
chainLoop = true;
chainLoopLengthZ = 6;
chainLoopPosition = "bottom"; // [bottom, top]

/* [General] */
letterThickness = 3; // [1 : 15]

/* [Icons] */
iconColor = "white"; // [pink, red, black, white, yellow, blue, green]
//TODO: Where is the heart icon, man?  "Put your heart into it."
leftIconType = "Moon";   // [Bass Clef, Creeper, Light Bulb, Moon, Rebel, Trooper, Aqua Dude, Cat, Fan, Spur, Mario, Luigi, Sun, Thundercat, Treble Clef]
rightIconType = "Sun";          // [Bass Clef, Creeper, Light Bulb, Moon, Rebel, Trooper, Aqua Dude, Cat, Fan, Spur, Mario, Luigi, Sun, Thundercat, Treble Clef]

// This is the x off set of the icons
xIconOffset = -100; // [10:200]

// This is the y off set of the icons
yIconOffset = 3;  // [1:200]

// This is the X,Y scale of the icons.
leftIconXyScale = 0.5;  // [0.1 : 0.05 : 5]

rightIconXyScale = 0.25; // [0.1 : 0.05 : 5]

leftIconHeight = 2.5; // [0.1: 0.1 :5]
rightIconHeight = 4.0; // [0.1: 0.1 :5]

/* [Top Text] */
topText = "Firstnesto Lastquez";
topTextColor = "white"; // [pink, red, black, white, yellow, blue, green]
topTextFont = "Times";

/* [Hidden] */

use <../name-tag.scad>

nametag(baseColor = baseColor,
        baseThickness = baseThickness,
        borderColor = borderColor,
        chainLoop = chainLoop,
        chainLoopLengthZ = chainLoopLengthZ,
        chainLoopPosition = chainLoopPosition,
        iconColor = iconColor,
        letterThickness = letterThickness,
        roundedCorners = true,
        topText = topText,
        topTextSize = 13,
        topTextColor = topTextColor,
        topTextFont = topTextFont,
        bottomText = bottomText,
        bottomTextFont = bottomTextFont,
        bottomTextOffsetX = bottomTextOffsetX,
        bottomTextOffsetY = bottomTextOffsetY,
//        font=font,
        leftIconType = leftIconType,
        leftIconHeight = leftIconHeight,
        rightIconHeight = rightIconHeight,
//        rightIconOffsetY = 0,
        rightIconType = rightIconType,
        xIconOffset = xIconOffset,
        yIconOffset = yIconOffset,
        baseWidth = baseWidth,
        showBorder = showBorder);


Cut out hole on bottom of switch part

Cut out hole on bottom of switch part

//
//  Strain relief for FTC robot main power switch
//

use <../common/extrusions.scad>

$fn = 20;

thick = 3; // thickness of walls and base
LARGE = 100; // Something larger than any demension - for O to become U
EPSILON = 0.1; // Small emount to extend so that unions and intersections are clean

// Switch side and walls
module switch_part() {
    switch_w = 30; // width - x
    wall_h = 10; // height - z - of walls - will be slightly less than switch walls
                 // so that tape or ziptie is firm against top of the switch
    switch_d = 30; // depth - y
    ro = 1; // outside-facing radii
    ri = 0.2; // radii of switch channel inside walls
    side_w = 5; // side part of base without hole
    front_d = 5; // front part of base without hole
    hole_r = 5;
    hole_w = switch_w - 2 * side_w; // width of hole
    base_w = switch_w + 2*thick;
    difference() {
        translate([0, switch_d, 0]) rotate([90, 0, 0])
            O_channel(base_w, wall_h+thick, switch_w, LARGE,
                thick, thick,
                ro, ri,switch_d);
        translate([thick + side_w, front_d, -EPSILON])
            oblong(hole_w, LARGE, hole_r, thick + 2*EPSILON);
    }
}

// Support below lugs - depth - in y-direction -  is {lug_d}
module lugs_support(lug_d) {
    lug_w = 10; // width - x
    lug_h = 5; // height - z
    lug_center_w = 5; // width of center protrusion
    lug_r = 1; // radii of curve in center protrusion
    lug_pad_h = 0.5; // the base of the lug is slightly elevated (z) from the switch base
    lug_gap_d = 0.5; // a small gap in x between the start of the center protrusion.
                     // This is because the lugs are slightly taller (z) where they
                     // attach to the switch

    // The difference is to round the base of the lug - so that tape does not have to
    // wrap around a sharp corner.
    difference() {
        union() {
            cube([lug_w, lug_d+EPSILON, thick]);
            translate([lug_w, lug_d-lug_gap_d, lug_h+thick+lug_pad_h])
                rotate([90, 180, 0])
                    T_channel(lug_center_w, lug_h, lug_w, thick+lug_pad_h,
                        (lug_w-lug_center_w)/2,
                        lug_r, lug_d-lug_gap_d);
        }
        translate([-thick, lug_d+EPSILON, -thick]) rotate([90, 0, 0])
            O_channel(lug_w+2*thick, thick+thick, lug_w, LARGE,
                thick, thick,
                0, lug_r, lug_d+2*EPSILON);
    }
}

module switch_strain_relief() {
    lug_d = 10; // depth - y - of lug
    lug_off = 5; // offset in x of lug position
    translate([0, lug_d, 0]) switch_part();
    translate([lug_off, 0, 0]) lugs_support(lug_d);
}

switch_strain_relief();

//
//  Strain relief for FTC robot main power switch
//

use <../common/extrusions.scad>

$fn = 20;

thick = 3; // thickness of walls and base
LARGE = 100; // Something larger than any demension - for O to become U
EPSILON = 0.1; // Small emount to extend so that unions and intersections are clean

// Switch side and walls
module switch_part() {
    switch_w = 30; // width - x
    wall_h = 20; // height - z - of walls - will be slightly less than switch walls
                 // so that tape or ziptie is firm against top of the switch
    switch_d = 30; // depth - y
    ro = 1; // outside-facing radii
    ri = 0.2; // radii of switch channel inside walls

    base_w = switch_w + 2*thick;
    translate([0, switch_d, 0]) rotate([90, 0, 0])
        O_channel(base_w, wall_h+thick, switch_w, LARGE,
            thick, thick,
            ro, ri,switch_d);
}

// Support below lugs - depth - in y-direction -  is {lug_d}
module lugs_support(lug_d) {
    lug_w = 10; // width - x
    lug_h = 5; // height - z
    lug_center_w = 5; // width of center protrusion
    lug_r = 1; // radii of curve in center protrusion
    lug_pad_h = 0.5; // the base of the lug is slightly elevated (z) from the switch base
    lug_gap_d = 0.5; // a small gap in x between the start of the center protrusion.
                     // This is because the lugs are slightly taller (z) where they
                     // attach to the switch

    // The difference is to round the base of the lug - so that tape does not have to
    // wrap around a sharp corner.
    difference() {
        union() {
            cube([lug_w, lug_d+EPSILON, thick]);
            translate([lug_w, lug_d-lug_gap_d, lug_h+thick+lug_pad_h])
                rotate([90, 180, 0])
                    T_channel(lug_center_w, lug_h, lug_w, thick+lug_pad_h,
                        (lug_w-lug_center_w)/2,
                        lug_r, lug_d-lug_gap_d);
        }
        translate([-thick, lug_d+EPSILON, -thick]) rotate([90, 0, 0])
            O_channel(lug_w+2*thick, thick+thick, lug_w, LARGE,
                thick, thick,
                0, lug_r, lug_d+2*EPSILON);
    }
}

module switch_strain_relief() {
    lug_d = 10; // depth - y - of lug
    lug_off = 5; // offset in x of lug position
    translate([0, lug_d, 0]) switch_part();
    translate([lug_off, 0, 0]) lugs_support(lug_d);
}

switch_strain_relief();


Tweak tolerances

Tweak tolerances

added 0.5mm

// Connectors

LineSensorHolder_Con_Def = [[0,0,0], [0,0,-1], 0,0,0];

module LineSensorHolder_STL() {

    printedPart("printedparts/LineSensorHolder.scad", "Line Sensor Holder", "LineSensorHolder_STL()") {

        view(t=[0,0,0],r=[72,0,130],d=400);

        if (DebugCoordinateFrames) frame();
        if (DebugConnectors) {
            connector(LineSensorHolder_Con_Def);
        }

        color(Level3PlasticColor) {
            if (UseSTL) {
                import(str(STLPath, "LineSensorHolder.stl"));
            } else {
                LineSensorHolder_Model();
            }
        }
    }
}

module LineSensorHolder_Model()
{
    // local vars

    // model
    difference() {
        union() {
            // surrounds for sensors
            for (i=[0,1])
                mirror([i,0,0])
                translate([4,-5,-GroundClearance+2])
                cube([15,10,10]);

            // walls
            for (i=[0,1])
                mirror([i,0,0])
                translate([3,-5,-GroundClearance+2])
                cube([dw,10,GroundClearance-2]);

            // pin plate
            translate([-5,-5,-2])
                cube([10, 10, 2]);
        }

        // hollow for Pin
        cylinder(r=PinDiameter/2, h=20, center=true);

        // hollow for sensors
        for (i=[0,1])
            mirror([i,0,0])
            translate([6.2,-3.5,-GroundClearance-1])
            cube([11,6.5,14]);
    }
}

// Connectors

LineSensorHolder_Con_Def = [[0,0,0], [0,0,-1], 0,0,0];

module LineSensorHolder_STL() {

    printedPart("printedparts/LineSensorHolder.scad", "Line Sensor Holder", "LineSensorHolder_STL()") {

        view(t=[0,0,0],r=[72,0,130],d=400);

        if (DebugCoordinateFrames) frame();
        if (DebugConnectors) {
            connector(LineSensorHolder_Con_Def);
        }

        color(Level3PlasticColor) {
            if (UseSTL) {
                import(str(STLPath, "LineSensorHolder.stl"));
            } else {
                LineSensorHolder_Model();
            }
        }
    }
}

module LineSensorHolder_Model()
{
    // local vars

    // model
    difference() {
        union() {
            // surrounds for sensors
            for (i=[0,1])
                mirror([i,0,0])
                translate([4,-5,-GroundClearance+2])
                cube([15,10,10]);

            // walls
            for (i=[0,1])
                mirror([i,0,0])
                translate([3,-5,-GroundClearance+2])
                cube([dw,10,GroundClearance-2]);

            // pin plate
            translate([-5,-5,-2])
                cube([10, 10, 2]);
        }

        // hollow for Pin
        cylinder(r=PinDiameter/2, h=20, center=true);

        // hollow for sensors
        for (i=[0,1])
            mirror([i,0,0])
            translate([6.7,-3,-GroundClearance-1])
            cube([10.5,6,14]);
    }
}


Added coupling feature to shell

Added coupling feature to shell

// Copyright 2017 Arthur Davis (thingiverse.com/artdavis)
// This file is licensed under a Creative Commons Attribution 4.0
// International License.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// Length of the Egg Casing Shell
case_length = 78; // [60:2:100]
// Coupler Shoulder Length
coupler_shoulder_len = 6.0; // [1.0:1.0:25.0]
// Coupler Shoulder Diameter
coupler_shoulder_diam = 18.7; // [10.0:0.2:50.0]
// Fitting Shoulder Length
coupler_fitting_len = 12.0; // [5.0:1.0:25.0]
// Fitting Shoulder Diameter
coupler_fitting_diam = 17.9; // [10.0:0.2:50.0]
// Wall thickness
wall_th = 2.0; // [1.0:0.2:4.0]
// Coupler Fraction
coupler_fract = 0.4; // [0.0:0.05:1.0]
// Coupler Thickness
coupler_th = 2.0; // [0.0:0.2:4.0]

/* [Hidden] */
// Special variables for facets/arcs
$fn = 48;

// Incremental offset to make good overlap for CSG operations
delta = 0.1;

// Coupler extension to overlap with egg shell
coupler_extra = 50.0;

// Number of steps to sample the half profile of the shell
steps = 100;

// Egg profile computing function
function egg(x, l=case_length)= 0.9*l*pow(1-x/l, 2/3)*sqrt(1-pow(1-x/l, 2/3));

// Create egg profile
module egg_profile(length=case_length, offset=0, steps=steps) {
    ss = length / (steps-1); // step size
    v1 = [for (x=[0:ss:length]) [egg(x, length), x + offset]];
    // Make absolute sure the last point bring the profile
    // back to the axis
    v2 = concat(v1, [[0, length + offset]]);
    // Close the loop
    v3 = concat(v2, [[0, offset]]);
        polygon(points = v3);
}

// Create a solid egg part
module solid_egg(length=case_length, offset=0, steps=steps) {
    rotate_extrude(convexity = 10) {
        egg_profile(length=length, offset=offset, steps=steps);
    }
}

// Create shell coupling feature
// thick: Thickness of the coupling feature
// fract: Fraction of shell to cover with coupling feature (between 0 and 1)
module shell_coupler(length=case_length, offset=0,
                     thick=coupler_th, fract=coupler_fract, steps=steps) {
    rotate(a=[90,0,-90]){
        difference() {
            union() {
                linear_extrude(height=thick, convexity=10) {
                    egg_profile(length=length, offset=offset, steps=steps);}
                mirror(v=[1, 0, 0]) {
                    linear_extrude(height=thick, convexity=10) {
                        egg_profile(length=length, offset=offset, steps=steps);}
                }
            }
        cube(size=[200, 2*(1-fract)*length, 200], center=true);
        }
    }
}

rotate(a = [0, 90.0000000000, 0])
{
	difference() {
		difference() {
			union() {
                shell_coupler(length=case_length + 2*coupler_th,
                              offset=-coupler_th, fract=coupler_fract);
                solid_egg(length=case_length, offset=0, steps=steps);
				difference() {
					union() {
						translate(v = [0, 0, -coupler_shoulder_len]) {
							cylinder(d = coupler_shoulder_diam,
                                     h = coupler_shoulder_len + coupler_extra);
						}
						translate(v = [0, 0,
                                -(coupler_shoulder_len+coupler_fitting_len)]) {
							cylinder(d = coupler_fitting_diam,
                                     h = coupler_fitting_len + delta);
						}
					}
					translate(v = [0, 0,
                    -(coupler_shoulder_len + coupler_fitting_len + delta/2.)]) {
						cylinder(d = coupler_fitting_diam - 2 * wall_th,
                                 h = coupler_shoulder_len + coupler_extra + coupler_fitting_len + delta);
					}
				}
			}
            solid_egg(case_length - 2*wall_th, wall_th);
		}
		translate(v = [0, -100.0000000000, -100.0000000000]) {
			cube(size = 200);
		}
	}
}

// Copyright 2017 Arthur Davis (thingiverse.com/artdavis)
// This file is licensed under a Creative Commons Attribution 4.0
// International License.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// Coupler Shoulder Length
coupler_shoulder_len = 6.0; // [1.0:1.0:25.0]
// Coupler Shoulder Diameter
coupler_shoulder_diam = 18.7; // [10.0:0.2:50.0]
// Fitting Shoulder Length
coupler_fitting_len = 12.0; // [5.0:1.0:25.0]
// Fitting Shoulder Diameter
coupler_fitting_diam = 17.9; // [10.0:0.2:50.0]

/* [Hidden] */
// Special variables for facets/arcs
$fn = 48;

// Incremental offset to make good overlap for CSG operations
delta = 0.1;

// Coupler extension to overlap with egg shell
coupler_extra = 50.0;

// Wall thickness of the fitting
wall_th = 2.0;

rotate(a = [0, 90.0000000000, 0]) {
	difference() {
		difference() {
			union() {
				rotate_extrude(convexity = 10) {
					polygon(paths = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]], points = [[0.0, 0.0], [5.72665976254, 0.787878787879], [8.05038105423, 1.57575757576], [9.80018127265, 2.36363636364], [11.2472643828, 3.15151515152], [12.4972974066, 3.93939393939], [13.6047652817, 4.72727272727], [14.6021984362, 5.51515151515], [15.5108932745, 6.30303030303], [16.3457085347, 7.09090909091], [17.1175079667, 7.87878787879], [17.8345245286, 8.66666666667], [18.5031770294, 9.45454545455], [19.1285862759, 10.2424242424], [19.7149158759, 11.0303030303], [20.2656055159, 11.8181818182], [20.7835355337, 12.6060606061], [21.2711460408, 13.3939393939], [21.7305250773, 14.1818181818], [22.1634751175, 14.9696969697], [22.5715640991, 15.7575757576], [22.9561651671, 16.5454545455], [23.3184880451, 17.3333333333], [23.6596040934, 18.1212121212], [23.9804665411, 18.9090909091], [24.2819269813, 19.696969697], [24.5647489379, 20.4848484848], [24.8296191131, 21.2727272727], [25.0771567804, 22.0606060606], [25.3079216807, 22.8484848485], [25.5224206998, 23.6363636364], [25.7211135462, 24.4242424242], [25.9044176022, 25.2121212121], [26.072712088, 26.0], [26.2263416488, 26.7878787879], [26.3656194555, 27.5757575758], [26.4908298928, 28.3636363636], [26.6022308959, 29.1515151515], [26.7000559829, 29.9393939394], [26.7845160264, 30.7272727273], [26.8558007977, 31.5151515152], [26.9140803113, 32.303030303], [26.9595059942, 33.0909090909], [26.9922116996, 33.8787878788], [27.0123145812, 34.6666666667], [27.0199158429, 35.4545454545], [27.0151013739, 36.2424242424], [26.9979422797, 37.0303030303], [26.9684953169, 37.8181818182], [26.9268032365, 38.6060606061], [26.8728950426, 39.3939393939], [26.8067861681, 40.1818181818], [26.7284785707, 40.9696969697], [26.6379607503, 41.7575757576], [26.5352076876, 42.5454545455], [26.4201807035, 43.3333333333], [26.2928272365, 44.1212121212], [26.1530805355, 44.9090909091], [26.0008592627, 45.696969697], [25.8360670014, 46.4848484848], [25.6585916611, 47.2727272727], [25.46830477, 48.0606060606], [25.2650606441, 48.8484848485], [25.0486954195, 49.6363636364], [24.819025931, 50.4242424242], [24.5758484169, 51.2121212121], [24.3189370276, 52.0], [24.0480421065, 52.7878787879], [23.7628882124, 53.5757575758], [23.4631718379, 54.3636363636], [23.1485587749, 55.1515151515], [22.8186810642, 55.9393939394], [22.4731334524, 56.7272727273], [22.111469262, 57.5151515152], [21.7331955563, 58.303030303], [21.3377674507, 59.0909090909], [20.9245813851, 59.8787878788], [20.4929671158, 60.6666666667], [20.0421781222, 61.4545454545], [19.5713800259, 62.2424242424], [19.0796364944, 63.0303030303], [18.5658919259, 63.8181818182], [18.0289499606, 64.6060606061], [17.4674465095, 65.3939393939], [16.8798154681, 66.1818181818], [16.2642445037, 66.9696969697], [15.6186171137, 67.7575757576], [14.9404352801, 68.5454545455], [14.2267140118, 69.3333333333], [13.4738339769, 70.1212121212], [12.6773295295, 70.9090909091], [11.8315731081, 71.696969697], [10.9292852524, 72.4848484848], [9.96073328705, 73.2727272727], [8.91233085017, 74.0606060606], [7.76396461901, 74.8484848485], [6.4832197059, 75.6363636364], [5.01030931987, 76.4242424242], [3.20274294789, 77.2121212121], [0.0, 78.0], [0.0000000000, 0]]);
				}
				difference() {
					union() {
						translate(v = [0, 0, -coupler_shoulder_len]) {
							cylinder(d = coupler_shoulder_diam, h = coupler_shoulder_len + coupler_extra);
						}
						translate(v = [0, 0, -(coupler_shoulder_len + coupler_fitting_len)]) {
							cylinder(d = coupler_fitting_diam, h = coupler_fitting_len + delta);
						}
					}
					translate(v = [0, 0, -(coupler_shoulder_len + coupler_fitting_len + delta/2.)]) {
						cylinder(d = coupler_fitting_diam - 2 * wall_th, h = coupler_shoulder_len + coupler_extra + coupler_fitting_len + delta);
					}
				}
			}
			rotate_extrude() {
				polygon(paths = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]], points = [[0.0, 2.0], [5.43298490292, 2.74747474747], [7.63754100017, 3.49494949495], [9.29760787405, 4.24242424242], [10.6704815939, 4.9898989899], [11.8564103601, 5.73737373737], [12.9070850108, 6.48484848485], [13.8533677471, 7.23232323232], [14.7154628502, 7.9797979798], [15.5074670714, 8.72727272727], [16.2396870454, 9.47474747475], [16.9199335271, 10.2222222222], [17.5542961561, 10.9696969697], [18.1476331336, 11.7171717172], [18.7038945489, 12.4646464646], [19.2263436946, 13.2121212121], [19.7177131986, 13.9595959596], [20.1803180387, 14.7070707071], [20.6161391759, 15.4545454545], [21.02688665, 16.202020202], [21.4140479914, 16.9494949495], [21.7789259277, 17.696969697], [22.1226681454, 18.4444444444], [22.446291063, 19.1919191919], [22.7506990262, 19.9393939394], [23.0366999567, 20.6868686869], [23.3050182231, 21.4343434343], [23.5563053124, 22.1818181818], [23.7911487403, 22.9292929293], [24.0100795432, 23.6767676768], [24.2135786127, 24.4242424242], [24.4020820823, 25.1717171717], [24.5759859303, 25.9191919192], [24.7356499297, 26.6666666667], [24.8814010515, 27.4141414141], [25.0135364065, 28.1616161616], [25.1323257958, 28.9090909091], [25.2380139269, 29.6565656566], [25.3308223427, 30.404040404], [25.410951102, 31.1515151515], [25.478580244, 31.898989899], [25.5338710646, 32.6464646465], [25.5769672253, 33.3939393939], [25.607995715, 34.1414141414], [25.6270676796, 34.8888888889], [25.634279133, 35.6363636364], [25.6297115599, 36.3838383838], [25.6134324192, 37.1313131313], [25.585495557, 37.8787878788], [25.545941532, 38.6262626263], [25.4947978609, 39.3737373737], [25.4320791851, 40.1212121212], [25.357787362, 40.8686868687], [25.2719114811, 41.6161616162], [25.1744278062, 42.3636363636], [25.0652996418, 43.1111111111], [24.9444771218, 43.8585858586], [24.8118969183, 44.6060606061], [24.6674818646, 45.3535353535], [24.5111404885, 46.101010101], [24.3427664477, 46.8484848485], [24.1622378587, 47.595959596], [23.9694165085, 48.3434343434], [23.7641469364, 49.0909090909], [23.5462553704, 49.8383838384], [23.3155484981, 50.5858585859], [23.0718120518, 51.3333333333], [22.8148091779, 52.0808080808], [22.5442785605, 52.8282828283], [22.2599322565, 53.5757575758], [21.9614531967, 54.3232323232], [21.6484922916, 55.0707070707], [21.3206650702, 55.8181818182], [20.9775477614, 56.5656565657], [20.6186727072, 57.3131313131], [20.2435229661, 58.0606060606], [19.8515259294, 58.8080808081], [19.4420457252, 59.5555555556], [19.0143741159, 60.303030303], [18.5677195117, 61.0505050505], [18.1011935973, 61.797979798], [17.6137949041, 62.5454545455], [17.1043884241, 63.2929292929], [16.5716800218, 64.0404040404], [16.0141839056, 64.7878787879], [15.430180683, 65.5353535354], [14.8176623899, 66.2828282828], [14.1742591119, 67.0303030303], [13.4971389342, 67.7777777778], [12.7828681319, 68.5252525253], [12.0272100664, 69.2727272727], [11.2248257692, 70.0202020202], [10.3688090856, 70.7676767677], [9.44992645182, 71.5151515152], [8.45528824247, 72.2626262626], [7.36581258726, 73.0101010101], [6.15074690047, 73.7575757576], [4.75337038039, 74.5050505051], [3.0384997198, 75.2525252525], [0.0, 76.0], [0.0000000000, 2.0000000000]]);
			}
		}
		translate(v = [0, -100.0000000000, -100.0000000000]) {
			cube(size = 200);
		}
	}
}


extruder: wip stuff

extruder: wip stuff

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>;
include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>

module capmount(show_sensor=false,lower_height=12,mount_lower=12,height=10,thickness=5,screws_spacing=21,screw_offset=[1,0],screws_diameter=4,sensor_spacing=3,sensor_height=[15,40,5],sensor_diameter=12)
{
    mount_start = 1.7+sensor_spacing+screws_spacing+screws_diameter+2*screw_offset[0];
    if(show_sensor)
    {
        translate([-8+sensor_diameter/2+thickness,-.5+mount_start+thickness+sensor_diameter/2,-39])
        {
            translate([0,0,sensor_height[1]+sensor_height[2]])
                fncylindera(d=sensor_diameter-0.5,h=sensor_height[0]);
            translate([0,0,sensor_height[2]])
                %fncylindera(d=sensor_diameter-0.5,h=sensor_height[1]);
            fncylindera(d=sensor_diameter-0.5,h=sensor_height[2]);
        }
    }

    //  Mount
    $fn=50;
    difference() {
        translate([0,0,-lower_height])
            cube([thickness+1, mount_start, height+lower_height]);

        //Screws 1
        translate([2*e, 4+screw_offset[0], height/2+screw_offset[1]])
        {
            rotate([0,90,0])
            {
                fncylindera(d=screws_diameter, h=thickness+1);
                translate([0,0,2.5])
                    fncylindera(h = 4, d=8.2, $fn=6);
            }
            //Screws 2
            translate([0,screws_spacing,0])
                rotate([0,90,0])
                {
                    fncylindera(d=screws_diameter, h=thickness+1);
                    translate([0,0,2.5])
                        fncylindera(h = 4, d=8.2, $fn=6);
                }
        }

    }
    //Sensor mount
    $fn=200;
    translate([-8,-.3,0])
        difference() {
            union() {
                translate([sensor_diameter/2+thickness,mount_start+thickness+sensor_diameter/2, -lower_height])
                    fncylindera(d=sensor_diameter+2*thickness, h=height+lower_height-mount_lower);

            }
            translate([sensor_diameter/2+thickness,mount_start+thickness+sensor_diameter/2, -height/2])
                fncylindera(d=sensor_diameter+0,5, h=2*height, center=true);

            cutoff=[1,2];
            translate([0,mount_start, -lower_height-e])
                cubea([cutoff[0],sensor_diameter+thickness*2,height+lower_height-mount_lower+2*e],[1,1,1]);

            translate([sensor_diameter+thickness*2,mount_start, -lower_height-e])
                cubea([cutoff[1],sensor_diameter+thickness*2,height+lower_height-mount_lower+2*e],[-1,1,1]);
        }
}

house_bearing=bearing_MR128;
guidler_bearing=bearing_625;

house_padding_wd=11*mm;
house_padding_h=4*mm;

filapath_width=10*mm;

// 4mm ptfe tube
filament_path_d = 4*mm;

// offset from the center of the bolt to the filament path
bolt_center_offset = 4.2*mm;

hotend_mount_h=10.5*mm;

// from E3D V6 heatsink drawing
// http://wiki.e3d-online.com/wiki/File:DRAWING-V6-175-SINK.png
// each entry == dia + h
hotmount_d_h=[[16*mm,3.7*mm],[12*mm,6*mm],[16*mm,3*mm]];
hotmount_outer_size=max(vec_i(hotmount_d_h,0))+10*mm;
hotmount_h_offset=-2*mm;
// which side does hotend slide in (x-axis, i.e. -1 is left, 1 is right)
hotmount_clamp_side=1*mm;

hotmount_tolerance=1.05*mm;

// hotmount clamp screws distance from center
hotmount_clamp_thread = ThreadM3;
hotmount_clamp_nut = MHexNutM3;

hotmount_clamp_screw_dia = lookup(ThreadSize, hotmount_clamp_thread);
hotmount_clamp_screws_dist = hotmount_d_h[1][1] + 2*hotmount_clamp_screw_dia;
hotmount_clamp_pad = 2.5*mm;
hotmount_clamp_thickness = 5*mm;
hotmount_clamp_y = 2*(hotmount_clamp_screws_dist + hotmount_clamp_screw_dia + hotmount_clamp_pad);
hotmount_clamp_height = hotmount_d_h[1][1];

// length of the guidler bearing bolt/screw
guidler_bolt_h=10*mm;

guidler_mount_w=guidler_bearing[2];
guidler_mount_d=9*mm;

guidler_w=max(guidler_mount_w+7, guidler_bearing[2]*2.8);
guidler_d=5;
guidler_h=12;
guidler_extra_h_up=guidler_bearing[1]/2+hotmount_clamp_screw_dia/2;

guidler_mount_off_d=-guidler_bearing[1]/1.7;
guidler_mount_off_h=-guidler_bearing[1]/1.7;

extruder_guidler_mount_off_y = guidler_mount_off_d - guidler_bearing[1]/2;

house_inner_w=max(guidler_w+3, filament_d*2 + 4*2);

guidler_screws_thread = ThreadM3;
guidler_screws_thread_dia= lookup(ThreadSize, guidler_screws_thread);
guidler_screws_distance=6*mm;
guidler_screws_mount_d = 10*mm;
guidler_screws_mount_d_offset = 0*mm;

xcarriage_mount_hole_distance = 23*mm;
xcarriage_mount_w = xcarriage_mount_hole_distance + 6*mm;
xcarriage_mount_d = 6*mm;
xcarriage_mount_h = xcarriage_mount_w;

// 80t + 20t w/228-2GT-6 belt
gears_distance=38.8*mm;
motor_offset_y = 20*mm;
motor_offset_z = pythag_leg(motor_offset_y,gears_distance);

extruder_motor_type = NemaShort;
extruder_motor = dict_replace_multiple(Nema17,
        [
        [NemaShort, 33*mm],
        [NemaFrontAxleLength, 22*mm]
        ]);

extruder_motor_mount_thickness = 5*mm;
extruder_motor_side = motorWidth(extruder_motor);
extruder_motor_length = motorLength(extruder_motor);

house_w = max(house_inner_w+2*house_bearing[2], hotmount_outer_size, xcarriage_mount_w);
house_d=house_bearing[1]/2+house_padding_wd;
house_h=house_bearing[1]+house_padding_h;

house_guidler_screw_h = guidler_screws_thread_dia+8*mm;
house_guidler_screw_h_offset = house_h/2 + guidler_screws_thread_dia + 4*mm;

alpha = 0.7;
/*alpha = 1;*/
color_xcarriage = [0.3,0.8,0.3, alpha];
color_hotend = [0.8,0.4,0.4, alpha];
color_extruder = [0.2,0.6,0.9, alpha];
color_guidler = [0.4,0.5,0.8, alpha];

extruder_guidler_roll = 45;

house_offset_xcarriage_y = house_d+19*mm;
house_offset_xcarriage_z = -25;

// extruder connection point for guidler
extruder_conn_guidler = [ [0, extruder_guidler_mount_off_y, guidler_mount_off_h],  [1,0,0]];
extruder_conn_hotend = [[0,0,-house_h/2+hotmount_h_offset-0.1],[0,0,1]];
extruder_conn_xcarriage=[[0, house_offset_xcarriage_y, house_offset_xcarriage_z],[0,1,0]];
/*extruder_conn_xcarriage=[[house_w/2+10, 15,-36],[-1,0,0]];*/

extruder_conn_hotmount_clamp=[[house_w/2*(hotmount_clamp_side), 0,-house_h/2+hotmount_h_offset -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2], [0,0,0]];
hotmount_clamp_conn = [[0,0,0],[0,0,0]];

module extruder_guidler_mount(){

    translate([0,guidler_mount_off_d-guidler_bearing[1]/2, guidler_mount_off_h])
    {
        cubea([guidler_mount_w,guidler_mount_d,guidler_mount_d],align=[0,0,-1], extrasize=[0,5,0], extrasize_align=[0,1,0]);
        rotate([0,90,0])
        {
            fncylindera(d=guidler_mount_d, h=guidler_mount_w);
        }

        translate([0,0,-guidler_mount_d/2-1])
            cubea([house_w,guidler_mount_d,guidler_mount_d/2+1],align=[0,0,-1], extrasize=[0,5,0], extrasize_align=[0,1,0]);
    }
}

module extruder_own(show_filament=true)
{
    color(color_extruder)
    difference()
    {
        union(){

            house_w_extended = max(house_w, extruder_motor_mount_thickness*2+extruder_motor_length);
            hull()
            {
                // main house
                translate([0,bolt_center_offset,0])
                {
                    /*rotate([0,90,0])*/
                    /*fncylindera(h=house_w, d=house_d);*/
                    cubea(size=[house_w,house_d,house_h], align=[0,0,0]);
                }

                // hotend mount housing
                translate([0,0,-house_h/2 + hotmount_h_offset])
                {
                    /*cubea([house_w/2, hotmount_outer_size, hotend_mount_h], align=[-1,0,-1], extrasize=[guidler_mount_w/2,0,-hotmount_h_offset], extrasize_align=[1,-1,1]);*/
                    cubea([house_w, hotmount_outer_size, hotend_mount_h], align=[0,0,-1]);
                }

            }

            hull()
            {
                // main house
                translate([0,bolt_center_offset,0])
                {
                    /*rotate([0,90,0])*/
                    /*fncylindera(h=house_w, d=house_d);*/
                    cubea(size=[house_w, house_d, house_h], align=[0,0,0]);
                }

                // guidler screws mount
                translate([0, guidler_screws_mount_d_offset, house_guidler_screw_h_offset])
                {
                    cubea([house_w, guidler_screws_mount_d, house_guidler_screw_h], align=[0,0,0]);

                    for(i=[-1,1])
                    translate([i*(guidler_screws_distance), 0, 0])
                    rotate([0,90,90])
                    fncylindera(d=house_guidler_screw_h, h=guidler_screws_mount_d);
                }

                // mount onto xcarriage
                translate([0,0,0])
                    translate([0, house_offset_xcarriage_y, house_offset_xcarriage_z])
                    cubea([xcarriage_mount_w,xcarriage_mount_d,xcarriage_mount_h],[0,-1,0]);

                /*translate([0, house_offset_xcarriage_y, house_offset_xcarriage_z])*/
                /*cubea([xcarriage_mount_w,house_offset_xcarriage_y,xcarriage_mount_h],[0,-1,0]);*/
            }

            translate([0,bolt_center_offset,0])
            translate([0,motor_offset_y,motor_offset_z])
            {
                difference()
                {
                    slide_dist=4;
                    union()
                    {
                        // front mount plate for motor
                        translate([-house_w/2,0,0])
                        {
                            cubea([extruder_motor_mount_thickness, extruder_motor_side+slide_dist, extruder_motor_side],[1,0,0]);

                            // back mount plate for motor
                            translate([extruder_motor_length,0,0])
                                cubea([extruder_motor_mount_thickness, extruder_motor_side+slide_dist, extruder_motor_side],[1,0,0]);
                        }
                    }

                    translate([-extruder_motor_mount_thickness-1,0,0])
                        rotate([90,90,90])
                        linear_extrude(extruder_motor_mount_thickness+2)
                        stepper_motor_mount(17, slide_distance=4, mochup=false);
                }
            }

            // guidler mount
            extruder_guidler_mount();
        }

        translate([0,bolt_center_offset,0])
        translate([0,motor_offset_y,motor_offset_z])
        {
            slide_dist=4;
            cubea([extruder_motor_length, extruder_motor_side+slide_dist, extruder_motor_side],[1,0,0]);

            translate([-extruder_motor_mount_thickness-1,0,0])
                rotate([90,90,90])
                linear_extrude(extruder_motor_mount_thickness+2)
                stepper_motor_mount(17, slide_distance=4, mochup=false);
        }

        // guidler screws cutouts
        for(i=[-1,1])
        translate([i*(guidler_screws_distance), guidler_screws_mount_d_offset, house_guidler_screw_h_offset])
        {
            r= guidler_screws_thread_dia/2 * 1.1;
            cubea([r*2, guidler_screws_mount_d+1, r]);
            for(v=[-1,1])
            translate([0,0, v*r/2])
            {
                rotate([0,90,90])
                    fncylindera(r=r,h=guidler_screws_mount_d+1);
            }

            // guidler screw nuts drop-in slots
            translate([0,0, -r*2])
            cubea([nut_m3[1]*1.1,nut_m3[2]*1.25,house_guidler_screw_h], align=[0,0,1], extrasize=[0,0,1], extrasize_align=[0,0,1]);
        }

        // filament path ptfe line cutout
        fncylindera(d=filament_path_d, h=50, align=[0,0,0]);

        translate([0,0,-house_h/2+hotmount_h_offset])
        {
            hotmount_cutout(extend_cut=true);

            // clamp mount screw holes
            for(i=[-1,1])
            {
                translate([0, i*hotmount_clamp_screws_dist, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
                    rotate([0,90,0])
                    fncylindera(r=screw_m3[0], h=house_w+1);
            }

            translate([house_w/2 * (hotmount_clamp_side), 0, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
            {
                cubea([hotmount_clamp_thickness+0.2, hotmount_clamp_y+0.2, hotmount_clamp_height+0.2], align=[-hotmount_clamp_side,0,0], extrasize=[1,0,0], extrasize_align=[hotmount_clamp_side,0,0]);
            }
        }

        // cutout pivot to make sure guidler can rotate out
        guidler_pivot_r=pythag_hyp(abs(guidler_mount_off_d),abs(guidler_mount_off_h))+(guidler_bearing[1])/2;
        difference()
        {
            union()
            {
                /*translate([-house_inner_w/2,0,0])*/
                    /*translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])*/
                    /*rotate([0,90,0])*/
                    /*pie_slice(guidler_pivot_r*1.05, 120, 180, house_inner_w, $fn=50);*/

                translate([-house_inner_w/2,0,0])
                    translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])
                    rotate([0,90,0])
                    pie_slice(guidler_mount_d/2*1.25, 0, 180, house_inner_w/2 - guidler_mount_w/2, $fn=50);

                translate([guidler_mount_w/2,0,0])
                    translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])
                    rotate([0,90,0])
                    pie_slice(guidler_mount_d/2*1.25, 0, 180, house_inner_w/2 - guidler_mount_w/2, $fn=50);
            }

            extruder_guidler_mount();
        }

        // cutout inside main house for guidler
        guidler_pivot_r=pythag_hyp(guidler_mount_off_d,guidler_mount_off_h);
        translate([-house_inner_w/2,-guidler_bearing[1]/2, 0])
        {
            rotate([0,90,0])
            {
                pie_slice(r=guidler_bearing[1]/2*1.02, start_angle=0, end_angle=360, h=house_inner_w);
            }
        }

        /*translate([0,-guidler_bearing[1]/2,0])*/
        /*rotate([0,90,0])*/
        /*fncylindera(d=guidler_bearing[1]*1.05, h=house_inner_w);*/

        translate([0,bolt_center_offset,0])
        {
            // left bearing
            translate([-house_w/2-2*e,0,0])
                rotate([90,0,90])
                fncylindera(d=house_bearing[1]*1.02, h=house_bearing[2], align=[0,0,1]);

            // right bearing
            translate([house_w/2+2*e,0,0])
                rotate([90,0,90])
                fncylindera(d=house_bearing[1]*1.02, h=house_bearing[2], align=[0,0,-1]);

            // hobbed bolt
            rotate([90,0,90])
                fncylindera(d=8.5, h=house_w+1);
        }

        // guidler mount bolt hole
        translate([0,guidler_mount_off_d-guidler_bearing[1]/2, guidler_mount_off_h])
            rotate([0,90,0])
            fncylindera(r=screw_m3[0],h=guidler_w+1);
    }

    if(show_filament)
    {
        // filament
        fncylindera(d=filament_d, h=50);
    }

    /*translate([0,0,-house_h/2])*/
}

module hotmount_cutout(extend_cut=false)
{
    // cutout of j-head/e3d heatsink mount
    heights=vec_i(hotmount_d_h,1);
    for(e=v_itrlen(hotmount_d_h))
    {
        hs=v_sum(heights,e-1);
        translate([0,0,-hs])
        {
            d=hotmount_d_h[e][0]*hotmount_tolerance;
            h=hotmount_d_h[e][1]*hotmount_tolerance;
            fncylindera(d=d,h=h,align=[0,0,-1]);
            if(extend_cut)
            {
                cubea([house_w/2+1,d,h],align=[hotmount_clamp_side,0,-1]);
            }
        }
    }
}

module hotmount_clamp()
{
    difference()
    {
        union()
        {
            translate([house_w/2 * hotmount_clamp_side, 0, 0]);
            {
                cubea([hotmount_clamp_thickness, hotmount_clamp_y, hotmount_clamp_height], align=[-hotmount_clamp_side,0,0]);
            }

            difference()
            {
                translate([house_w/2 * hotmount_clamp_side, 0, 0]);
                {
                    cubea([house_w/2, hotmount_d_h[1][0], hotmount_clamp_height], align=[-hotmount_clamp_side,0,0]);
                }

                translate([(-house_w/2 * hotmount_clamp_side) + (-0.5*hotmount_clamp_side), 0, hotmount_d_h[0][1]+hotmount_d_h[1][1]/2])
                {
                    hotmount_cutout(extend_cut = false);
                }
            }

        }

        // clamp mount screw holes
        for(i=[-1,1])
        {
            translate([0, i*hotmount_clamp_screws_dist, 0])
                rotate([0,90,0])
                fncylindera(r=screw_m3[0], h=hotmount_clamp_thickness, align=[0,0,-hotmount_clamp_side], extra_h=1);
        }
    }
}

// guidler connection point
guidler_conn = [ [0, guidler_mount_off_d, guidler_mount_off_h],  [1,0,0]];

module guidler()
{
    // everything inside this module is relative to the center of the
    // bearing (that clamps the filament)
    color(color_guidler)
    difference()
    {
        union()
        {

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, 0])
                    cubea([guidler_w, guidler_d, guidler_h], align=[0,1,0]);

                // guidler bearing bolt holder
                rotate([0,90,0])
                    fncylindera(d=guidler_bearing[0]*1.5,h=guidler_w);
            }
            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, 0])
                    cubea([guidler_w, guidler_d, guidler_h], align=[0,1,0], extrasize=[0,0,guidler_extra_h_up], extrasize_align=[0,0,1]);

                // guidler mount point
                translate([0,guidler_mount_off_d, guidler_mount_off_h])
                    rotate([0,90,0])
                    fncylindera(d=guidler_mount_d,h=guidler_w);
            }

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, guidler_h])
                    cubea([guidler_w, guidler_d, 1], align=[0,1,0]);

                // guidler screws mount
                for(i=[-1,1])
                translate([i*(guidler_screws_distance),guidler_mount_off_d-guidler_mount_d/2, house_guidler_screw_h_offset])
                rotate([0,90,90])
                fncylindera(r=guidler_screws_thread_dia/2*3,h=guidler_d, align=[0,0,1]);

            }
        }

        // cutouts for clamping screws
        for(i=[-1,1])
        translate([i*(guidler_screws_distance),guidler_mount_off_d-guidler_mount_d/2, house_guidler_screw_h_offset])
        {
            r= guidler_screws_thread_dia/2*1.1;
            cubea([r*2,house_w+1,r]);
            for(v=[-1,1])
                translate([0,0, v*r/2])
                {
                    rotate([0,90,90])
                        fncylindera(r=r,h=house_w+1);
                }
        }

        // port hole to see bearing
        translate([0,-guidler_bearing[1]/2,0])
            cubea([guidler_bearing[0]*1.1, 100, guidler_bearing[1]/2], align=[0,0,1]);

        // cutout middle mount point pivot
        translate([0,guidler_mount_off_d, guidler_mount_off_h])
            rotate([0,90,0])
            {
                fncylindera(d=guidler_mount_d*1.25,h=guidler_mount_w*1.1);
            }

        // mount bolt hole
        translate([0,guidler_mount_off_d, guidler_mount_off_h])
            rotate([0,90,0])
            fncylindera(r=screw_m3[0],h=100);

        // guidler bearing bolt holder cutout
        union() {
            cubea([guidler_bolt_h*1.05+2*e,guidler_bearing[0]*1.05,guidler_bearing[0]*1.05],align=[0,1,0]);

            rotate([0,90,0])
                fncylindera(d=guidler_bearing[0]*1.05, h=guidler_bolt_h*1.05);
        }

        // guidler bearing cutout
        rotate([0,90,0])
            fncylindera(d=guidler_bearing[1]*1.1, h=guidler_bearing[2]*1.1);
    }

    %if(show_extras)
    {
        rotate([0,90,0])
        {
            fncylindera(d=guidler_bearing[1], h=guidler_bearing[2]);
            fncylindera(d=guidler_bearing[0], h=guidler_bolt_h);
        }
    }
}

module extras()
{
    hob_offset_x = -5*mm;

    // hobbed bolt
    // measurements from
    // http://wiki.e3d-online.com/wiki/E3D_HobbGoblin_Drawings
    hob_l = 64.5*mm;

    // center of the hob (from left side)
    hob_center = 37*mm;

    hob_conn_extruder=[[-hob_l/2+hob_center,0,0], [0,0,0]];

    attach([[0,bolt_center_offset,0],[0,0,0]], hob_conn_extruder)
    {
        /*connector(hob_conn_extruder);*/

        // hob-goblin hobbed bolt
        union()
        {
            thread_left = 20.5;
            thread_right = 14;
            hob_width = 4.2;
            color([0.1,0.2,0.3])
                translate([-hob_l/2,0,0])
                rotate([0,90,0])
                fncylindera(h=thread_left, d=8, align=[0,0,1]);

            color([0.6,0.6,0.6])
            difference()
            {
                translate([-hob_l/2+thread_left,0,0])
                    rotate([0,90,0])
                    fncylindera(h=hob_l-thread_left-thread_right, d=8, align=[0,0,1]);

                translate([-hob_l/2+hob_center,0,0])
                    rotate([0,90,0])
                    fncylindera(h=hob_width, d=8.1);
            }
            color([0.6,0.2,0.3])
                translate([-hob_l/2+hob_center,0,0])
                rotate([0,90,0])
                fncylindera(h=hob_width, d=7);

            color([0.1,0.2,0.3])
            translate([hob_l/2-thread_right,0,0])
                rotate([0,90,0])
                fncylindera(h=thread_right, d=8, align=[0,0,1]);

            /*rotate([0,90,0])*/
                /*fncylindera(h=hob_l, d=8);*/

            /*translate([-hob_l/2+hob_center,0,0])*/
                /*rotate([0,90,0])*/
                /*fncylindera(h=hob_width, d=8.1);*/

        }

        hob_conn_cog = [[-hob_l/2 + 13*mm,0,0], [-1,0,0]];

        /*connector(hob_conn_cog);*/
        // gear/cog
        // attach onto hobbed bolt
        cog_conn = [[11*mm,0,0],[1,0,0]];
        attach(hob_conn_cog, cog_conn, 019)
        {
            rotate([270,0,90])
                import("stl/gt2_extruder_cog_80tooth.stl");
        }
    }

    // motor/belt
    translate([-1,bolt_center_offset,0])
    translate([-house_w/2+extruder_motor_mount_thickness,motor_offset_y,motor_offset_z])
    {
        // main motor body
        motor(extruder_motor, extruder_motor_type, dualAxis=false, orientation=[0,90,0]);

        translate([-1,0,0])
            rotate([0,0,180])
            import("stl/GT2_20tooth.stl");
    }

    // hotend
    hotend_conn =[[0,0,21.35*mm],[0,0,1]];
    attach(extruder_conn_hotend, hotend_conn)
        color(color_hotend)
        rotate([90,0,270])
        import("stl/E3D_V6_1.75mm_Universal_HotEnd_Mockup.stl");

    // x carriage
    xcarriage_conn =[[-0.4,-8.5,-1],[0,-1,0]];
    attach(extruder_conn_xcarriage, xcarriage_conn)
    {
        /*connector(xcarriage_conn);*/
        color(color_xcarriage)
            translate([282*mm,-170,14])
            rotate([90,180,180])
            import("../wilson/x-carriage.stl");
    }
}

module extruder()
{
    extruder_own();

    attach(extruder_conn_guidler, guidler_conn, extruder_guidler_roll)
    {
        guidler(show_extras=true);
    }

    attach(extruder_conn_hotmount_clamp, hotmount_clamp_conn)
    {
        /*connector(hotmount_clamp_conn);*/
        hotmount_clamp(); }

    if(true) { extras(); } }

module print()
{
    extruder_conn_layflat = [[-house_w/2,0,0],[-1,0,0]];
    attach([[0,0,0],[0,0,-1]], extruder_conn_layflat)
    {
        /*connector(extruder_conn_layflat);*/
        extruder_own(false,false);
    }

    guidler_conn_layflat = [ [0, guidler_mount_off_d-guidler_mount_d/2, guidler_mount_off_h],  [0,-1,0]]; attach([[34*mm,10*mm,0],[0,0,-1]], guidler_conn_layflat)
    {
        /*connector(guidler_conn_layflat);*/
        guidler(false);
    }

    hotmount_clamp_conn_layflat=[[0,0,0],[-1,0,0]];
    attach([[54*mm,0,0],[0,0,1]], hotmount_clamp_conn_layflat)
    {
        /*connector(hotmount_clamp_conn);*/
        hotmount_clamp();
    }
}

/*extruder();*/
/*print();*/

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>;
include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>

module capmount(show_sensor=false,lower_height=12,mount_lower=12,height=10,thickness=5,screws_spacing=21,screw_offset=[1,0],screws_diameter=4,sensor_spacing=3,sensor_height=[15,40,5],sensor_diameter=12)

{
    mount_start = 1.7+sensor_spacing+screws_spacing+screws_diameter+2*screw_offset[0];
    if(show_sensor)
    {
        translate([-8+sensor_diameter/2+thickness,-.5+mount_start+thickness+sensor_diameter/2,-39])
        {
            translate([0,0,sensor_height[1]+sensor_height[2]])
                fncylindera(d=sensor_diameter-0.5,h=sensor_height[0]);
            translate([0,0,sensor_height[2]])
                %fncylindera(d=sensor_diameter-0.5,h=sensor_height[1]);
            fncylindera(d=sensor_diameter-0.5,h=sensor_height[2]);
        }
    }

    //  Mount
    $fn=50;
    difference() {
        translate([0,0,-lower_height])
            cube([thickness+1, mount_start, height+lower_height]);

        //Screws 1
        translate([2*e, 4+screw_offset[0], height/2+screw_offset[1]])
        {
            rotate([0,90,0])
            {
                fncylindera(d=screws_diameter, h=thickness+1);
                translate([0,0,2.5])
                    fncylindera(h = 4, d=8.2, $fn=6);
            }
            //Screws 2
            translate([0,screws_spacing,0])
                rotate([0,90,0])
                {
                    fncylindera(d=screws_diameter, h=thickness+1);
                    translate([0,0,2.5])
                        fncylindera(h = 4, d=8.2, $fn=6);
                }
        }

    }
    //Sensor mount
    $fn=200;
    translate([-8,-.3,0])
        difference() {
            union() {
                translate([sensor_diameter/2+thickness,mount_start+thickness+sensor_diameter/2, -lower_height])
                    fncylindera(d=sensor_diameter+2*thickness, h=height+lower_height-mount_lower);

            }
            translate([sensor_diameter/2+thickness,mount_start+thickness+sensor_diameter/2, -height/2])
                fncylindera(d=sensor_diameter+0,5, h=2*height, center=true);

            cutoff=[1,2];
            translate([0,mount_start, -lower_height-e])
                cubea([cutoff[0],sensor_diameter+thickness*2,height+lower_height-mount_lower+2*e],[1,1,1]);

            translate([sensor_diameter+thickness*2,mount_start, -lower_height-e])
                cubea([cutoff[1],sensor_diameter+thickness*2,height+lower_height-mount_lower+2*e],[-1,1,1]);
        }
}

house_bearing=bearing_MR128;
guidler_bearing=bearing_625;

house_padding_wd=11*mm;
house_padding_h=4*mm;

filapath_width=10*mm;

// 4mm ptfe tube
filament_path_d = 4*mm;

// offset from the center of the bolt to the filament path
bolt_center_offset = 4.2*mm;

hotend_mount_h=10.5*mm;

// from E3D V6 heatsink drawing
// http://wiki.e3d-online.com/wiki/File:DRAWING-V6-175-SINK.png
// each entry == dia + h
hotmount_d_h=[[16*mm,3.7*mm],[12*mm,6*mm],[16*mm,3*mm]];
hotmount_outer_size=max(vec_i(hotmount_d_h,0))+10*mm;
hotmount_h_offset=-2*mm;
// which side does hotend slide in (x-axis, i.e. -1 is left, 1 is right)
hotmount_clamp_side=1*mm;

hotmount_tolerance=1.05*mm;

// hotmount clamp screws distance from center
hotmount_clamp_thread = ThreadM3;
hotmount_clamp_nut = MHexNutM3;

hotmount_clamp_screw_dia = lookup(ThreadSize, hotmount_clamp_thread);
hotmount_clamp_screws_dist = hotmount_d_h[1][1] + 2*hotmount_clamp_screw_dia;
hotmount_clamp_pad = 2.5*mm;
hotmount_clamp_thickness = 5*mm;
hotmount_clamp_y = 2*(hotmount_clamp_screws_dist + hotmount_clamp_screw_dia + hotmount_clamp_pad);
hotmount_clamp_height = hotmount_d_h[1][1];

// length of the guidler bearing bolt/screw
guidler_bolt_h=10*mm;

guidler_mount_w=guidler_bearing[2];
guidler_mount_d=9*mm;

guidler_w=max(guidler_mount_w+7, guidler_bearing[2]*2.8);
guidler_d=5;
guidler_h=12;
guidler_extra_h_up=guidler_bearing[1]/2+hotmount_clamp_screw_dia/2;

guidler_mount_off_d=-guidler_bearing[1]/1.7;
guidler_mount_off_h=-guidler_bearing[1]/1.7;

extruder_guidler_mount_off_y = guidler_mount_off_d - guidler_bearing[1]/2;

house_inner_w=max(guidler_w+3, filament_d*2 + 4*2);

guidler_screws_thread = ThreadM3;
guidler_screws_thread_dia= lookup(ThreadSize, guidler_screws_thread);
guidler_screws_distance=6*mm;
guidler_screws_mount_d = 10*mm;
guidler_screws_mount_d_offset = 0*mm;

xcarriage_mount_hole_distance = 23*mm;
xcarriage_mount_w = xcarriage_mount_hole_distance + 6*mm;
xcarriage_mount_d = 6*mm;
xcarriage_mount_h = xcarriage_mount_w;

house_w = max(house_inner_w+2*house_bearing[2], hotmount_outer_size, xcarriage_mount_w);
house_d=house_bearing[1]/2+house_padding_wd;
house_h=house_bearing[1]+house_padding_h;

house_guidler_screw_h = guidler_screws_thread_dia+8*mm;
house_guidler_screw_h_offset = house_h/2 + guidler_screws_thread_dia + 4*mm;

extruder_motor = dict_replace_multiple(Nema17,
        [
        [NemaFrontAxleLength, 22*mm]
        ]);

// 80t + 20t w/228-2GT-6 belt
gears_distance=38.8*mm;
motor_offset_x = -8*mm;
motor_offset_y = 20*mm;
motor_offset_z = pythag_leg(motor_offset_y,gears_distance);

alpha = 0.7;
/*alpha = 1;*/
color_xcarriage = [0.3,0.8,0.3, alpha];
color_hotend = [0.8,0.4,0.4, alpha];
color_extruder = [0.2,0.6,0.9, alpha];
color_guidler = [0.4,0.5,0.8, alpha];

extruder_guidler_roll = 45;

house_offset_xcarriage_y = house_d+19*mm;
house_offset_xcarriage_z = -25;

// extruder connection point for guidler
extruder_conn_guidler = [ [0, extruder_guidler_mount_off_y, guidler_mount_off_h],  [1,0,0]];
extruder_conn_hotend = [[0,0,-house_h/2+hotmount_h_offset-0.1],[0,0,1]];
extruder_conn_xcarriage=[[0, house_offset_xcarriage_y, house_offset_xcarriage_z],[0,1,0]];
/*extruder_conn_xcarriage=[[house_w/2+10, 15,-36],[-1,0,0]];*/

extruder_conn_hotmount_clamp=[[house_w/2*(hotmount_clamp_side), 0,-house_h/2+hotmount_h_offset -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2], [0,0,0]];
hotmount_clamp_conn = [[0,0,0],[0,0,0]];

module extruder_guidler_mount(){

    translate([0,guidler_mount_off_d-guidler_bearing[1]/2, guidler_mount_off_h])
    {
        cubea([guidler_mount_w,guidler_mount_d,guidler_mount_d],align=[0,0,-1], extrasize=[0,5,0], extrasize_align=[0,1,0]);
        rotate([0,90,0])
        {
            fncylindera(d=guidler_mount_d, h=guidler_mount_w);
        }

        translate([0,0,-guidler_mount_d/2-1])
            cubea([house_w,guidler_mount_d,guidler_mount_d/2+1],align=[0,0,-1], extrasize=[0,5,0], extrasize_align=[0,1,0]);
    }
}

module extruder_own(show_filament=true)
{
    color(color_extruder)
    difference()
    {
        union(){

            hull()
            {
                // main house
                translate([0,bolt_center_offset,0])
                {
                    /*rotate([0,90,0])*/
                    /*fncylindera(h=house_w, d=house_d);*/
                    cubea(size=[house_w,house_d,house_h], align=[0,0,0]);
                }

                // hotend mount housing
                translate([0,0,-house_h/2 + hotmount_h_offset])
                {
                    /*cubea([house_w/2, hotmount_outer_size, hotend_mount_h], align=[-1,0,-1], extrasize=[guidler_mount_w/2,0,-hotmount_h_offset], extrasize_align=[1,-1,1]);*/
                    cubea([house_w, hotmount_outer_size, hotend_mount_h], align=[0,0,-1]);
                }

            }

            hull()
            {
                // main house
                translate([0,bolt_center_offset,0])
                {
                    /*rotate([0,90,0])*/
                    /*fncylindera(h=house_w, d=house_d);*/
                    cubea(size=[house_w, house_d, house_h], align=[0,0,0]);
                }

                // guidler screws mount
                translate([0, guidler_screws_mount_d_offset, house_guidler_screw_h_offset])
                {
                    cubea([house_w, guidler_screws_mount_d, house_guidler_screw_h], align=[0,0,0]);

                    for(i=[-1,1])
                    translate([i*(guidler_screws_distance), 0, 0])
                    rotate([0,90,90])
                    fncylindera(d=house_guidler_screw_h, h=guidler_screws_mount_d);
                }

                // mount onto xcarriage
                translate([0,0,0])
                    translate([0, house_offset_xcarriage_y, house_offset_xcarriage_z])
                    cubea([xcarriage_mount_w,xcarriage_mount_d,xcarriage_mount_h],[0,-1,0]);

                /*translate([0, house_offset_xcarriage_y, house_offset_xcarriage_z])*/
                /*cubea([xcarriage_mount_w,house_offset_xcarriage_y,xcarriage_mount_h],[0,-1,0]);*/
            }

            translate([0,bolt_center_offset,0])
            translate([motor_offset_x,motor_offset_y,motor_offset_z])
            {
                difference()
                {
                    slide_dist=4;
                    mount_thickness = motor_offset_x+house_w/2;
                    side = motorWidth(extruder_motor);

                    translate([-mount_thickness,0,0])
                        cubea([mount_thickness, side+slide_dist, side],[1,0,0]);

                    translate([-mount_thickness-1,0,0])
                        rotate([90,90,90])
                        linear_extrude(mount_thickness+2)
                        stepper_motor_mount(17, slide_distance=4, mochup=false);
                }
            }

            // guidler mount
            extruder_guidler_mount();
        }

        translate([0,bolt_center_offset,0])
        translate([motor_offset_x,motor_offset_y,motor_offset_z])
        {
            slide_dist=4;
            side = motorWidth(extruder_motor);
                mount_thickness = motor_offset_x+house_w/2;

            cubea([motorLength(extruder_motor), side+slide_dist, side],[1,0,0]);

            translate([-mount_thickness-1,0,0])
                rotate([90,90,90])
                linear_extrude(mount_thickness+2)
                stepper_motor_mount(17, slide_distance=4, mochup=false);
        }

        // guidler screws cutouts
        for(i=[-1,1])
        translate([i*(guidler_screws_distance), guidler_screws_mount_d_offset, house_guidler_screw_h_offset])
        {
            r= guidler_screws_thread_dia/2 * 1.1;
            cubea([r*2, guidler_screws_mount_d+1, r]);
            for(v=[-1,1])
            translate([0,0, v*r/2])
            {
                rotate([0,90,90])
                    fncylindera(r=r,h=guidler_screws_mount_d+1);
            }

            // guidler screw nuts drop-in slots
            translate([0,0, -r*2])
            cubea([nut_m3[1]*1.1,nut_m3[2]*1.25,house_guidler_screw_h], align=[0,0,1], extrasize=[0,0,1], extrasize_align=[0,0,1]);
        }

        // filament path ptfe line cutout
        fncylindera(d=filament_path_d, h=50, align=[0,0,0]);

        translate([0,0,-house_h/2+hotmount_h_offset])
        {
            hotmount_cutout(extend_cut=true);

            // clamp mount screw holes
            for(i=[-1,1])
            {
                translate([0, i*hotmount_clamp_screws_dist, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
                    rotate([0,90,0])
                    fncylindera(r=screw_m3[0], h=house_w+1);
            }

            translate([house_w/2 * (hotmount_clamp_side), 0, -hotmount_d_h[0][1]-hotmount_d_h[1][1]/2])
            {
                cubea([hotmount_clamp_thickness+0.2, hotmount_clamp_y+0.2, hotmount_clamp_height+0.2], align=[-hotmount_clamp_side,0,0], extrasize=[1,0,0], extrasize_align=[hotmount_clamp_side,0,0]);
            }
        }

        // cutout pivot to make sure guidler can rotate out
        guidler_pivot_r=pythag_hyp(abs(guidler_mount_off_d),abs(guidler_mount_off_h))+(guidler_bearing[1])/2;
        difference()
        {
            union()
            {
                /*translate([-house_inner_w/2,0,0])*/
                    /*translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])*/
                    /*rotate([0,90,0])*/
                    /*pie_slice(guidler_pivot_r*1.05, 120, 180, house_inner_w, $fn=50);*/

                translate([-house_inner_w/2,0,0])
                    translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])
                    rotate([0,90,0])
                    pie_slice(guidler_mount_d/2*1.25, 0, 180, house_inner_w/2 - guidler_mount_w/2, $fn=50);

                translate([guidler_mount_w/2,0,0])
                    translate([0,extruder_guidler_mount_off_y, guidler_mount_off_h])
                    rotate([0,90,0])
                    pie_slice(guidler_mount_d/2*1.25, 0, 180, house_inner_w/2 - guidler_mount_w/2, $fn=50);
            }

            extruder_guidler_mount();
        }

        // cutout inside main house for guidler
        guidler_pivot_r=pythag_hyp(guidler_mount_off_d,guidler_mount_off_h);
        translate([-house_inner_w/2,-guidler_bearing[1]/2, 0])
        {
            rotate([0,90,0])
            {
                pie_slice(r=guidler_bearing[1]/2*1.02, start_angle=0, end_angle=360, h=house_inner_w);
            }
        }

        /*translate([0,-guidler_bearing[1]/2,0])*/
        /*rotate([0,90,0])*/
        /*fncylindera(d=guidler_bearing[1]*1.05, h=house_inner_w);*/

        translate([0,bolt_center_offset,0])
        {
            // left bearing
            translate([-house_w/2-2*e,0,0])
                rotate([90,0,90])
                fncylindera(d=house_bearing[1]*1.02, h=house_bearing[2], align=[0,0,1]);

            // right bearing
            translate([house_w/2+2*e,0,0])
                rotate([90,0,90])
                fncylindera(d=house_bearing[1]*1.02, h=house_bearing[2], align=[0,0,-1]);

            // hobbed bolt
            rotate([90,0,90])
                fncylindera(d=8.5, h=house_w+1);
        }

        // guidler mount bolt hole
        translate([0,guidler_mount_off_d-guidler_bearing[1]/2, guidler_mount_off_h])
            rotate([0,90,0])
            fncylindera(r=screw_m3[0],h=guidler_w+1);
    }

    if(show_filament)
    {
        // filament
        fncylindera(d=filament_d, h=50);
    }

    /*translate([0,0,-house_h/2])*/
}

module hotmount_cutout(extend_cut=false)
{
    // cutout of j-head/e3d heatsink mount
    heights=vec_i(hotmount_d_h,1);
    for(e=v_itrlen(hotmount_d_h))
    {
        hs=v_sum(heights,e-1);
        translate([0,0,-hs])
        {
            d=hotmount_d_h[e][0]*hotmount_tolerance;
            h=hotmount_d_h[e][1]*hotmount_tolerance;
            fncylindera(d=d,h=h,align=[0,0,-1]);
            if(extend_cut)
            {
                cubea([house_w/2+1,d,h],align=[hotmount_clamp_side,0,-1]);
            }
        }
    }
}

module hotmount_clamp()
{
    difference()
    {
        union()
        {
            translate([house_w/2 * hotmount_clamp_side, 0, 0]);
            {
                cubea([hotmount_clamp_thickness, hotmount_clamp_y, hotmount_clamp_height], align=[-hotmount_clamp_side,0,0]);
            }

            difference()
            {
                translate([house_w/2 * hotmount_clamp_side, 0, 0]);
                {
                    cubea([house_w/2, hotmount_d_h[1][0], hotmount_clamp_height], align=[-hotmount_clamp_side,0,0]);
                }

                translate([(-house_w/2 * hotmount_clamp_side) + (-0.5*hotmount_clamp_side), 0, hotmount_d_h[0][1]+hotmount_d_h[1][1]/2])
                {
                    hotmount_cutout(extend_cut = false);
                }
            }

        }

        // clamp mount screw holes
        for(i=[-1,1])
        {
            translate([0, i*hotmount_clamp_screws_dist, 0])
                rotate([0,90,0])
                fncylindera(r=screw_m3[0], h=hotmount_clamp_thickness, align=[0,0,-hotmount_clamp_side], extra_h=1);
        }
    }
}

// guidler connection point
guidler_conn = [ [0, guidler_mount_off_d, guidler_mount_off_h],  [1,0,0]];

module guidler()
{
    // everything inside this module is relative to the center of the
    // bearing (that clamps the filament)
    color(color_guidler)
    difference()
    {
        union()
        {

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, 0])
                    cubea([guidler_w, guidler_d, guidler_h], align=[0,1,0]);

                // guidler bearing bolt holder
                rotate([0,90,0])
                    fncylindera(d=guidler_bearing[0]*1.5,h=guidler_w);
            }
            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, 0])
                    cubea([guidler_w, guidler_d, guidler_h], align=[0,1,0], extrasize=[0,0,guidler_extra_h_up], extrasize_align=[0,0,1]);

                // guidler mount point
                translate([0,guidler_mount_off_d, guidler_mount_off_h])
                    rotate([0,90,0])
                    fncylindera(d=guidler_mount_d,h=guidler_w);
            }

            hull()
            {
                // guidler main block
                translate([0,guidler_mount_off_d-guidler_mount_d/2, guidler_h])
                    cubea([guidler_w, guidler_d, 1], align=[0,1,0]);

                // guidler screws mount
                for(i=[-1,1])
                translate([i*(guidler_screws_distance),guidler_mount_off_d-guidler_mount_d/2, house_guidler_screw_h_offset])
                rotate([0,90,90])
                fncylindera(r=guidler_screws_thread_dia/2*3,h=guidler_d, align=[0,0,1]);

            }
        }

        // cutouts for clamping screws
        for(i=[-1,1])
        translate([i*(guidler_screws_distance),guidler_mount_off_d-guidler_mount_d/2, house_guidler_screw_h_offset])
        {
            r= guidler_screws_thread_dia/2*1.1;
            cubea([r*2,house_w+1,r]);
            for(v=[-1,1])
                translate([0,0, v*r/2])
                {
                    rotate([0,90,90])
                        fncylindera(r=r,h=house_w+1);
                }
        }

        // port hole to see bearing
        translate([0,-guidler_bearing[1]/2,0])
            cubea([guidler_bearing[0]*1.1, 100, guidler_bearing[1]/2], align=[0,0,1]);

        // cutout middle mount point pivot
        translate([0,guidler_mount_off_d, guidler_mount_off_h])
            rotate([0,90,0])
            {
                fncylindera(d=guidler_mount_d*1.25,h=guidler_mount_w*1.1);
            }

        // mount bolt hole
        translate([0,guidler_mount_off_d, guidler_mount_off_h])
            rotate([0,90,0])
            fncylindera(r=screw_m3[0],h=100);

        // guidler bearing bolt holder cutout
        union() {
            cubea([guidler_bolt_h*1.05+2*e,guidler_bearing[0]*1.05,guidler_bearing[0]*1.05],align=[0,1,0]);

            rotate([0,90,0])
                fncylindera(d=guidler_bearing[0]*1.05, h=guidler_bolt_h*1.05);
        }

        // guidler bearing cutout
        rotate([0,90,0])
            fncylindera(d=guidler_bearing[1]*1.1, h=guidler_bearing[2]*1.1);
    }

    %if(show_extras)
    {
        rotate([0,90,0])
        {
            fncylindera(d=guidler_bearing[1], h=guidler_bearing[2]);
            fncylindera(d=guidler_bearing[0], h=guidler_bolt_h);
        }
    }
}

module extras()
{
    hob_offset_x = -5*mm;

    // hobbed bolt
    // measurements from
    // http://wiki.e3d-online.com/wiki/E3D_HobbGoblin_Drawings
    hob_l = 64.5*mm;

    // center of the hob (from left side)
    hob_center = 37*mm;

    hob_conn_extruder=[[-hob_l/2+hob_center,0,0], [0,0,0]];

    attach([[0,bolt_center_offset,0],[0,0,0]], hob_conn_extruder)
    {
        /*connector(hob_conn_extruder);*/

        // hob-goblin hobbed bolt
        union()
        {
            thread_left = 20.5;
            thread_right = 14;
            hob_width = 4.2;
            color([0.1,0.2,0.3])
                translate([-hob_l/2,0,0])
                rotate([0,90,0])
                fncylindera(h=thread_left, d=8, align=[0,0,1]);

            color([0.6,0.6,0.6])
            difference()
            {
                translate([-hob_l/2+thread_left,0,0])
                    rotate([0,90,0])
                    fncylindera(h=hob_l-thread_left-thread_right, d=8, align=[0,0,1]);

                translate([-hob_l/2+hob_center,0,0])
                    rotate([0,90,0])
                    fncylindera(h=hob_width, d=8.1);
            }
            color([0.6,0.2,0.3])
                translate([-hob_l/2+hob_center,0,0])
                rotate([0,90,0])
                fncylindera(h=hob_width, d=7);

            color([0.1,0.2,0.3])
            translate([hob_l/2-thread_right,0,0])
                rotate([0,90,0])
                fncylindera(h=thread_right, d=8, align=[0,0,1]);

            /*rotate([0,90,0])*/
                /*fncylindera(h=hob_l, d=8);*/

            /*translate([-hob_l/2+hob_center,0,0])*/
                /*rotate([0,90,0])*/
                /*fncylindera(h=hob_width, d=8.1);*/

        }

        hob_conn_cog = [[-hob_l/2 + 13*mm,0,0], [-1,0,0]];

        /*connector(hob_conn_cog);*/
        // gear/cog
        // attach onto hobbed bolt
        cog_conn = [[11*mm,0,0],[1,0,0]];
        attach(hob_conn_cog, cog_conn, 019)
        {
            rotate([270,0,90])
                import("stl/gt2_extruder_cog_80tooth.stl");
        }
    }

    // motor/belt
    translate([0,bolt_center_offset,0])
    translate([motor_offset_x-1,motor_offset_y,motor_offset_z])
    {
        // main motor body
        motor(extruder_motor, NemaShort, dualAxis=false, orientation=[0,90,0]);

        translate([-1,0,0])
            rotate([0,0,180])
            import("stl/GT2_20tooth.stl");
    }

    // hotend
    hotend_conn =[[0,0,21.35*mm],[0,0,1]];
    attach(extruder_conn_hotend, hotend_conn)
        color(color_hotend)
        rotate([90,0,270])
        import("stl/E3D_V6_1.75mm_Universal_HotEnd_Mockup.stl");

    // x carriage
    xcarriage_conn =[[-0.4,-8.5,-1],[0,-1,0]];
    attach(extruder_conn_xcarriage, xcarriage_conn)
    {
        /*connector(xcarriage_conn);*/
        color(color_xcarriage)
            translate([282*mm,-170,14])
            rotate([90,180,180])
            import("../wilson/x-carriage.stl");
    }
}

module extruder()
{
    extruder_own();

    attach(extruder_conn_guidler, guidler_conn, extruder_guidler_roll)
    {
        guidler(show_extras=true);
    }

    attach(extruder_conn_hotmount_clamp, hotmount_clamp_conn)
    {
        /*connector(hotmount_clamp_conn);*/
        hotmount_clamp(); }

    if(true) { extras(); } }

module print() { extruder_conn_layflat = [[-house_w/2,0,0],[-1,0,0]];
attach([[0,0,0],[0,0,-1]], extruder_conn_layflat) {
        /*connector(extruder_conn_layflat);*/
        extruder_own(false,false); }

    guidler_conn_layflat = [ [0, guidler_mount_off_d-guidler_mount_d/2,
    guidler_mount_off_h],  [0,-1,0]]; attach([[34*mm,10*mm,0],[0,0,-1]],
    guidler_conn_layflat) {
        /*connector(guidler_conn_layflat);*/
        guidler(false); }

    hotmount_clamp_conn_layflat=[[0,0,0],[-1,0,0]];
    attach([[54*mm,0,0],[0,0,1]], hotmount_clamp_conn_layflat) {
        /*connector(hotmount_clamp_conn);*/
        hotmount_clamp(); } }

/*extruder();*/
/*print();*/


added some more space for elements, so that glue can fit in as well + added visualization of how elements fit together


checking in before making knee wider

checking in before making knee wider

// try to draw Jansen linkage leg assembly as it might appear in steel

// these are for configuration "E" as referenced in other drawings
AC=17.5;
Ay =  3.318; Bx = 53.833;
BD = 48.020; BE = 46.977; BH = 40.359;
CD = 59.635; CH = 71.441; DE = 66.437;
EF = 47.467; FG = 75.792;
FH = 40.843; GH = 55.790;

DEleft = (DE*DE + BD*BD - BE*BE)/(2*DE);
FGleft = (FG*FG + FH*FH - GH*GH)/(2*FG);
DEperp = sqrt(BD*BD - DEleft*DEleft);
FGperp = sqrt(FH*FH - FGleft*FGleft);

echo(str("DEleft=",DEleft,"   DEperp=",DEperp));
echo(str("FGleft=",FGleft,"   FGperp=",FGperp));

r38 = (3/8)*2.54/2;  // radius of 3/8" bolt

a=360*$t;
legAssembly(a,0);
mirror([1,0,0]) legAssembly(180-a,1.2);
//legAssembly(100);

%translate([0,-93,0]) cube([200,2,2],center=true);

// -----------------------------------------------------------------

// plot a link shadow, a different way, to check kinematic correctness
module checkLink(xa,ya,xb,yb,ab) {
  *translate([(xa+xb)/2,(ya+yb)/2,-9])
    rotate([0,0,atan2(yb-ya,xb-xa)]) cube([ab,1,1],center=true);
}

function triK1(ax,ay,ca,bx,by,cb) = (cb*cb - ca*ca + ax*ax -bx*bx +ay*ay -by*by)/(2*(ax-bx));

// ===================================================================

module legAssembly(ang=0,linkOffset=0) {

// solve kinematics for given crank angle
xC = AC*cos(ang);
yC = AC*sin(ang)+Ay;
echo("C",xC,yC);

k1=(yC*yC - Bx*Bx + BD*BD - CD*CD + xC*xC)/(2*yC);
k2=(xC+Bx)/yC;
c=k1*k1-BD*BD+Bx*Bx;
b=2*(Bx-k1*k2);
a=k2*k2+1;
sgnD=(yC<0)?1:-1;
xD=(-b+sgnD*sqrt(b*b-4*a*c))/(2*a);
yD=sqrt(BD*BD - pow(xD+Bx,2));
echo("D",xD,yD,"CD err",sqrt(pow(xC-xD,2)+pow(yC-yD,2))-CD);

hipRot = atan2(yD,Bx+xD)-atan2(DEperp,DEleft);
echo("hipRot",hipRot);
xE = cos(hipRot) * (DEleft-DE) - sin(hipRot) * DEperp - Bx;
yE = sin(hipRot) * (DEleft-DE) + cos(hipRot) * DEperp;
/*
ke1=(yD*yD + xD*xD + DE*DE + BE*BE)/(2*yD);
ke2=(xD+Bx)/yD;
ae=2+ke2*ke2;
be=2*(Bx-ke1*ke2);
ce=ke1*ke1 - BE*BE +Bx*Bx;
echo("E abc:",ae,be,ce);
xE=(-be+sqrt(be*be-4*ae*ce))/(2*ae);
yE=sqrt(BE*BE - pow(xE+Bx,2));
*/
echo("E",xE,yE);

// this initial soln. seems wrong.
//xH=(BH*BH + xC*xC - CH*CH - Bx*Bx)/(2*(xC+Bx));
//yH=-sqrt(CH*CH - xC*xC + 2*xC*xH - xH*xH);
k1h=(xC*xC + yC*yC + BH*BH - CH*CH - Bx*Bx)/(2*yC);
k2h=-(xC+Bx)/yC;
ah=k2h*k2h+1;
bh=2*(k1h*k2h + Bx);
ch=k1h*k1h + Bx*Bx - BH*BH;
sgnH=(yC>0)?1:-1;
xH=(-bh+sgnH*sqrt(bh*bh-4*ah*ch))/(2*ah);
yH=-sqrt(BH*BH - pow(xH+Bx,2));
bhRot=atan2(yH,xH+Bx);
echo("H",xH,yH,"rot",bhRot,"CH err",sqrt(pow(xH-xC,2)+pow(yH-yC,2))-CH);

/*
k1f=(FH*FH - EF*EF - yE*yE - yH*yH + xE*xE - xH*xH) / (2*(yE-yH));
k2f=(xH-xE)/(yE-yH);
af=k2f*k2f+1;
bf=2*(k1f*k2f - xH - k2f*yH);
cf=xH*xH + yH*yH - 2*k1f*yH + k1f*k1f - FH*FH;
xF=(-bf-sqrt(bf*bf - 4*af*cf))/(2*af);
yF=k1f+k2f*xF;
*/
k2f = (yE-yH)/(xE-xH);
k1f = triK1(xE,yE,EF,xH,yH,FH);
af=k2f*k2f+1;
bf=2*(k2f*xE - k1f*k2f -yE);
cf=k1f*k1f - 2*k1f*xE + xE*xE + yE*yE - EF*EF;
yF=(-bf-sqrt(bf*bf - 4*af*cf))/(2*af);
xF=k1f-k2f*yF;
echo("F",xF,yF,"EF err",sqrt(pow(xF-xE,2)+pow(yF-yE,2))-EF);
echo("FH err",sqrt(pow(xF-xH,2)+pow(yF-yH,2))-FH);

//  -------------------------- crank-arm circle reference
%translate([0,Ay,0]) difference() {
  cylinder(r=AC,h=1,$fn=48,center=true);
  cylinder(r=2,h=2,center=true);
}

// draw the hip so that the main "plane", the ED centerline plane, is at z=0
translate([-Bx,0,0]) rotate([0,0,hipRot])
    translate([DEleft-DE,DEperp,0]) hip();
//translate([-Bx,0,2.5]) rotate([0,0,12.5]) translate([-DEleft,DEperp,0]) hip();
//translate([ Bx,0,0]) rotate([0,0,-20]) translate([DE-DEleft,DEperp,0]) mirror([1,0,0])
//  hip();
checkLink(-Bx,0,xD,yD,BD);
checkLink(-Bx,0,xE,yE,BE);
checkLink(xD,yD,xE,yE,DE);

translate([-Bx,0,0]) rotate([0,0,bhRot])
   BHlinks();
checkLink(-Bx,0,xH,yH,BH);

//translate([xC,yC,2]) rotate([0,0,142])
//   CDlink();
//translate([0,0,linkOffset-.5]) CDlink(xC,yC,xD,yD);
translate([xC,yC,linkOffset-.5]) rotate([0,0,atan2(yD-yC,xD-xC)])
  mirror([0,0,(linkOffset>0)?1:0]) crankLink(CD);
checkLink(xC,yC,xD,yD,CD);

//translate([0,0,linkOffset+1.8]) CDlink(xC,yC,xH,yH);
translate([xC,yC,linkOffset+1.8]) rotate([0,0,atan2(yH-yC,xH-xC)])
  mirror([0,0,(linkOffset>0)?1:0]) crankLink(CH);
checkLink(xC,yC,xH,yH,CH);

//%EFlink1(xE,yE,xF,yF);
translate([xF,yF,0]) rotate([0,0,atan2(yE-yF,xE-xF)]) EFlink();
checkLink(xE,yE,xF,yF,EF);

footRot = atan2(yH-yF,xH-xF)-atan2(FGperp,FGleft);
translate([xF,yF,0]) rotate([0,0,footRot])
   foot();
checkLink(xF,yF,xH,yH,FH);

} // end module legAssembly()

// -----------------------------------------------------------------

module foot() difference() {
  union() {
    hull() {  // FG
      cube([4,2.6,2.6],center=true);
      translate([FG-1.3,0,0]) cylinder(r=1.3,h=2.6,$fn=24,center=true);
    }
    for (z=[-1,1]) hull() {
      translate([-5,2,1.5*z])scale([3,5,1])cylinder(r=1,h=.4,$fn=64,center=true);
      translate([ 8,0,1.5*z])cylinder(r=.3,h=.4,center=true);
    }
    translate([FGleft,FGperp-5,0]) cube([2.6,6,2.6],center=true);
    translate([FGleft,FGperp-5,4.8]) cube([2.6,6,2.6],center=true);
    translate([FGleft,FGperp-5,2.5]) cube([2.6,2.6,7],center=true);
    color([.3,.3,.4,.8]) {
      translate([FGleft,FGperp-.5, 0 ]) cube([3.5,5,2.2],center=true);
      translate([FGleft,FGperp-.5,4.8]) cube([3.5,5,2.2],center=true);
    }
    hull() {
      translate([6,0,0]) sphere(.8);
      translate([FGleft,FGperp-5,0]) sphere(.8);
    }
    hull() {
      translate([FG-6,0,0]) sphere(.8);
      translate([FGleft,FGperp-6,0]) sphere(.8);
    }
    hull() {
      translate([FGleft,FGperp-5,5]) sphere(.8);
      translate([FGleft,0,0]) sphere(.8);
    }
  }

  cylinder(r=.3,h=4,center=true);
  cube([4.4,3,2],center=true);
  translate([FGleft,FGperp,0]) cylinder(r=.7,h=33,center=true);
}
$fn=12;

module hip() difference() {
  /*  old style, with forks ground from square tube :
  difference() {
    translate([DE/2,0,0]) cube([DE+3,2.6,2.6],center=true);
    cylinder(r=.5,h=6,center=true);
    cube([7,3,2],center=true);

    translate([DE,0,0]) {
      cylinder(r=.25,h=8,center=true);
      cube([5,3,2],center=true);
    }
  }
  */
  union() {
    translate([DE/2,0,0]) cube([DE-5,2.5,2.5],center=true); // top tube
    translate([DE-DEleft,-DEperp,-1.2]) cylinder(r=1.4,h=7.2,$fn=36); // axle

    // top tube fork plates
    translate([DE,0,0]) mirror([1,0,0]) eFork();
                                        eFork();

    hull() {  // diag tubes
      translate([DE-DEleft,-DEperp,0]) sphere(.8);
      translate([8,0,0]) sphere(.8);
    }
    hull() {
      translate([DE-DEleft,-DEperp,0]) sphere(.8);
      translate([DE-8,0,0]) sphere(.8);
    }

    // extra bracing
    translate([DE/2,-20,0]) rotate([0,90,0]) cylinder(r=.8,h=20,center=true);
    translate([DE-DEleft,-DEperp,4]) rotate([-105,0,0]) cylinder(r=.8,h=14);
  }

  // pivot holes
  for (x=[0,DE]) translate([x,0,0]) cylinder(r=r38,h=11,center=true);
}

module eFork() for(z=[-1,1]) hull() {
  translate([0,0,1.4*z]) cylinder(r=2,h=.3,$fn=24,center=true);
  translate([6,0,1.4*z]) cube([1,2,.3],center=true);
}

module crankLink(dx=CD) {
  cylinder(r=1.4,h=.7,$fn=24,center=true);
  color([0.3,0.3,0.4,0.9]) translate([dx-1,0,.6]) difference() {
    cube([5,2.7,2.2],center=true);
    #translate([1,0,0]) cylinder(r=.64,h=11,center=true);
  }
  translate([dx/2-1,0,0]) cube([dx-3,1.3,1.3],center=true);
}

module CDlink(cx=0,cy=0,dx=CD,dy=0) {
echo("CD",cx,cy,dx,dy);
  translate([dx,dy,0]) cylinder(r=1.4,h=.7,$fn=24,center=true);
  translate([cx,cy,0]) cylinder(r=1.4,h=.7,$fn=24,center=true);
  hull() {
    translate([dx,dy,0]) cylinder(r=.65,h=1.3,$fn=24,center=true);
    translate([cx,cy,0]) cylinder(r=.65,h=1.3,$fn=24,center=true);
  }
}

module EFlink() difference() {
  union() {
    color([.4,.4,.5,.9]) {
      translate([   1.5,0,0]) cube([6,3,2.5],center=true);
      translate([EF-1.5,0,0]) cube([6,3,2.5],center=true);
    }
    translate([EF/2,0,0]) cube([EF-4,2.6,2.6],center=true);
  }

  translate([EF,0,0]) cylinder(r=r38,h=3,center=true);
                      cylinder(r=r38,h=5,center=true);
}

module EFlink1(ex=0,ey=0,fx=EF,fy=0) {
echo("EF",ex,ey,fx,fy);
  difference() {
     union() {
       color([.3,.3,.4,.9]) {
         translate([ex,ey,0]) cube([4,3,2],center=true);
         translate([fx,fy,0]) cube([4,3,2],center=true);
       }
       hull() {
         translate([ex,ey,0]) cylinder(r=1.3,h=2.6,center=true);
         translate([fx,fy,0]) cylinder(r=1.3,h=2.6,center=true);
       }
     }

     translate([ex,ey,0]) cylinder(r=.7,h=3,center=true);
     translate([fx,fy,0]) cylinder(r=.7,h=3,center=true);
  }
}

// this link drawn with B axle at origin, always.
module BHlinks() {
  difference() {
    translate([0,0,2.4]) cylinder(r=1.4,h=13.5,$fn=36,center=true);
    translate([0,0,2.4]) cube([4,4,7.9],center=true);
  }

  for(z=[-2.4,7.2]) {
     hull() {
       translate([BH-3,0,z]) sphere(.8);
       translate([   0,0,z]) sphere(.8);
     }
  }

  hull() {
    translate([   4,0.5,-2.4]) sphere(.8);
    translate([BH-5,1, 6  ]) sphere(.8);
  }
  hull() {
    translate([   4,-.5, 7]) sphere(.8);
    translate([BH-5, -1, -2  ]) sphere(.8);
  }

  for(z=[-1.7,6.2]) translate([BH,0,z]) difference() {
     hull() {
       cylinder(r=3,h=.33,$fn=36);
       translate([-8,0,0]) cylinder(r=1,h=.33);
     }
     cylinder(r=.7,h=2,center=true);
  }

}
module BHlinks1() {
  translate([0,0, 6.8])                 BHlink();
  translate([0,0,-2  ]) mirror([0,0,1]) BHlink();
}
module BHlink() {
  cylinder(r=1.4,h=6,$fn=24);

  //%translate([BH/2-1,0,1.3]) cube([BH-2,2.5,2.5],center=true);
  for (q=[-1,1]) hull() {
    translate([  0 ,1.5*q,1]) sphere(0.8);
    translate([BH-3,1  *q,1]) sphere(0.8);
  }
  hull() {
    translate([  0 ,0,5]) sphere(0.8);
    translate([BH-3,0,1]) sphere(0.8);
  }

  translate([BH,0,-.3]) difference() {
     hull() {
       cylinder(r=3,h=.33,$fn=36);
       translate([-8,0,0]) cylinder(r=1,h=.33);
     }
     cylinder(r=.7,h=2,center=true);
  }
}

// try to draw Jansen linkage leg assembly as it might appear in steel

// these are for configuration "E" as referenced in other drawings
AC=17.5;
Ay =  3.318; Bx = 53.833;
BD = 48.020; BE = 46.977; BH = 40.359;
CD = 59.635; CH = 71.441; DE = 66.437;
EF = 47.467; FG = 75.792;
FH = 40.843; GH = 55.790;

DEleft = (DE*DE + BD*BD - BE*BE)/(2*DE);
FGleft = (FG*FG + FH*FH - GH*GH)/(2*FG);
DEperp = sqrt(BD*BD - DEleft*DEleft);
FGperp = sqrt(FH*FH - FGleft*FGleft);

echo(str("DEleft=",DEleft,"   DEperp=",DEperp));
echo(str("FGleft=",FGleft,"   FGperp=",FGperp));

a=360*$t;
legAssembly(a,0);
mirror([1,0,0]) legAssembly(180-a,1.2);
//legAssembly(100);

%translate([0,-93,0]) cube([200,2,2],center=true);

// -----------------------------------------------------------------

// plot a link shadow, a different way, to check kinematic correctness
module checkLink(xa,ya,xb,yb,ab) {
  *translate([(xa+xb)/2,(ya+yb)/2,-9])
    rotate([0,0,atan2(yb-ya,xb-xa)]) cube([ab,1,1],center=true);
}

function triK1(ax,ay,ca,bx,by,cb) = (cb*cb - ca*ca + ax*ax -bx*bx +ay*ay -by*by)/(2*(ax-bx));

// ===================================================================

module legAssembly(ang=0,linkOffset=0) {

// solve kinematics for given crank angle
xC = AC*cos(ang);
yC = AC*sin(ang)+Ay;
echo("C",xC,yC);

k1=(yC*yC - Bx*Bx + BD*BD - CD*CD + xC*xC)/(2*yC);
k2=(xC+Bx)/yC;
c=k1*k1-BD*BD+Bx*Bx;
b=2*(Bx-k1*k2);
a=k2*k2+1;
sgnD=(yC<0)?1:-1;
xD=(-b+sgnD*sqrt(b*b-4*a*c))/(2*a);
yD=sqrt(BD*BD - pow(xD+Bx,2));
echo("D",xD,yD,"CD err",sqrt(pow(xC-xD,2)+pow(yC-yD,2))-CD);

hipRot = atan2(yD,Bx+xD)-atan2(DEperp,DEleft);
echo("hipRot",hipRot);
xE = cos(hipRot) * (DEleft-DE) - sin(hipRot) * DEperp - Bx;
yE = sin(hipRot) * (DEleft-DE) + cos(hipRot) * DEperp;
/*
ke1=(yD*yD + xD*xD + DE*DE + BE*BE)/(2*yD);
ke2=(xD+Bx)/yD;
ae=2+ke2*ke2;
be=2*(Bx-ke1*ke2);
ce=ke1*ke1 - BE*BE +Bx*Bx;
echo("E abc:",ae,be,ce);
xE=(-be+sqrt(be*be-4*ae*ce))/(2*ae);
yE=sqrt(BE*BE - pow(xE+Bx,2));
*/
echo("E",xE,yE);

// this initial soln. seems wrong.
//xH=(BH*BH + xC*xC - CH*CH - Bx*Bx)/(2*(xC+Bx));
//yH=-sqrt(CH*CH - xC*xC + 2*xC*xH - xH*xH);
k1h=(xC*xC + yC*yC + BH*BH - CH*CH - Bx*Bx)/(2*yC);
k2h=-(xC+Bx)/yC;
ah=k2h*k2h+1;
bh=2*(k1h*k2h + Bx);
ch=k1h*k1h + Bx*Bx - BH*BH;
sgnH=(yC>0)?1:-1;
xH=(-bh+sgnH*sqrt(bh*bh-4*ah*ch))/(2*ah);
yH=-sqrt(BH*BH - pow(xH+Bx,2));
bhRot=atan2(yH,xH+Bx);
echo("H",xH,yH,"rot",bhRot,"CH err",sqrt(pow(xH-xC,2)+pow(yH-yC,2))-CH);

/*
k1f=(FH*FH - EF*EF - yE*yE - yH*yH + xE*xE - xH*xH) / (2*(yE-yH));
k2f=(xH-xE)/(yE-yH);
af=k2f*k2f+1;
bf=2*(k1f*k2f - xH - k2f*yH);
cf=xH*xH + yH*yH - 2*k1f*yH + k1f*k1f - FH*FH;
xF=(-bf-sqrt(bf*bf - 4*af*cf))/(2*af);
yF=k1f+k2f*xF;
*/
k2f = (yE-yH)/(xE-xH);
k1f = triK1(xE,yE,EF,xH,yH,FH);
af=k2f*k2f+1;
bf=2*(k2f*xE - k1f*k2f -yE);
cf=k1f*k1f - 2*k1f*xE + xE*xE + yE*yE - EF*EF;
yF=(-bf-sqrt(bf*bf - 4*af*cf))/(2*af);
xF=k1f-k2f*yF;
echo("F",xF,yF,"EF err",sqrt(pow(xF-xE,2)+pow(yF-yE,2))-EF);
echo("FH err",sqrt(pow(xF-xH,2)+pow(yF-yH,2))-FH);

//  -------------------------- crank-arm circle reference
%translate([0,Ay,0]) difference() {
  cylinder(r=AC,h=1,$fn=48,center=true);
  cylinder(r=2,h=2,center=true);
}

// draw the hip so that the main "plane", the ED centerline plane, is at z=0
translate([-Bx,0,0]) rotate([0,0,hipRot])
    translate([DEleft-DE,DEperp,0]) hip();
//translate([-Bx,0,2.5]) rotate([0,0,12.5]) translate([-DEleft,DEperp,0]) hip();
//translate([ Bx,0,0]) rotate([0,0,-20]) translate([DE-DEleft,DEperp,0]) mirror([1,0,0])
//  hip();
checkLink(-Bx,0,xD,yD,BD);
checkLink(-Bx,0,xE,yE,BE);
checkLink(xD,yD,xE,yE,DE);

translate([-Bx,0,0]) rotate([0,0,bhRot])
   BHlinks();
checkLink(-Bx,0,xH,yH,BH);

//translate([xC,yC,2]) rotate([0,0,142])
//   CDlink();
//translate([0,0,linkOffset-.5]) CDlink(xC,yC,xD,yD);
translate([xC,yC,linkOffset-.5]) rotate([0,0,atan2(yD-yC,xD-xC)])
  mirror([0,0,(linkOffset>0)?1:0]) crankLink(CD);
checkLink(xC,yC,xD,yD,CD);

//translate([0,0,linkOffset+1.8]) CDlink(xC,yC,xH,yH);
translate([xC,yC,linkOffset+1.8]) rotate([0,0,atan2(yH-yC,xH-xC)])
  mirror([0,0,(linkOffset>0)?1:0]) crankLink(CH);
checkLink(xC,yC,xH,yH,CH);

//%EFlink1(xE,yE,xF,yF);
translate([xF,yF,0]) rotate([0,0,atan2(yE-yF,xE-xF)]) EFlink();
checkLink(xE,yE,xF,yF,EF);

footRot = atan2(yH-yF,xH-xF)-atan2(FGperp,FGleft);
translate([xF,yF,0]) rotate([0,0,footRot])
   foot();
checkLink(xF,yF,xH,yH,FH);

} // end module legAssembly()

// -----------------------------------------------------------------

module foot() difference() {
  union() {
    hull() {  // FG
      cube([4,2.6,2.6],center=true);
      translate([FG-1.3,0,0]) cylinder(r=1.3,h=2.6,$fn=24,center=true);
    }
    for (z=[-1,1]) hull() {
      translate([-5,2,1.5*z])scale([3,5,1])cylinder(r=1,h=.4,$fn=64,center=true);
      translate([ 8,0,1.5*z])cylinder(r=.3,h=.4,center=true);
    }
    translate([FGleft,FGperp-5,0]) cube([2.6,6,2.6],center=true);
    translate([FGleft,FGperp-5,4.8]) cube([2.6,6,2.6],center=true);
    translate([FGleft,FGperp-5,2.5]) cube([2.6,2.6,7],center=true);
    color([.3,.3,.4,.8]) {
      translate([FGleft,FGperp-.5, 0 ]) cube([3.5,5,2.2],center=true);
      translate([FGleft,FGperp-.5,4.8]) cube([3.5,5,2.2],center=true);
    }
    hull() {
      translate([6,0,0]) sphere(.8);
      translate([FGleft,FGperp-5,0]) sphere(.8);
    }
    hull() {
      translate([FG-6,0,0]) sphere(.8);
      translate([FGleft,FGperp-6,0]) sphere(.8);
    }
    hull() {
      translate([FGleft,FGperp-5,5]) sphere(.8);
      translate([FGleft,0,0]) sphere(.8);
    }
  }

  cylinder(r=.3,h=4,center=true);
  cube([4.4,3,2],center=true);
  translate([FGleft,FGperp,0]) cylinder(r=.7,h=33,center=true);
}
$fn=12;

module hip() {
  //color("Black") cube([3,3,2.5],center=true);
  difference() {
    translate([DE/2,0,0]) cube([DE+3,2.6,2.6],center=true);
    cylinder(r=.5,h=6,center=true);
    cube([7,3,2],center=true);

    translate([DE,0,0]) {
      cylinder(r=.25,h=8,center=true);
      cube([5,3,2],center=true);
    }
  }
  translate([DE-DEleft,-DEperp,-1.2]) cylinder(r=1.4,h=7.2,$fn=36);
  hull() {
    translate([DE-DEleft,-DEperp,0]) sphere(.8);
    translate([8,0,0]) sphere(.8);
  }
  hull() {
    translate([DE-DEleft,-DEperp,0]) sphere(.8);
    translate([DE-8,0,0]) sphere(.8);
  }
  translate([DE/2,-20,0]) rotate([0,90,0]) cylinder(r=.8,h=20,center=true);
  translate([DE-DEleft,-DEperp,4]) rotate([-105,0,0]) cylinder(r=.8,h=14);
}

module crankLink(dx=CD) {
  cylinder(r=1.4,h=.7,$fn=24,center=true);
  color([0.3,0.3,0.4,0.9]) translate([dx-1,0,.6]) difference() {
    cube([5,2.7,2.2],center=true);
    #translate([1,0,0]) cylinder(r=.64,h=11,center=true);
  }
  translate([dx/2-1,0,0]) cube([dx-3,1.3,1.3],center=true);
}

module CDlink(cx=0,cy=0,dx=CD,dy=0) {
echo("CD",cx,cy,dx,dy);
  translate([dx,dy,0]) cylinder(r=1.4,h=.7,$fn=24,center=true);
  translate([cx,cy,0]) cylinder(r=1.4,h=.7,$fn=24,center=true);
  hull() {
    translate([dx,dy,0]) cylinder(r=.65,h=1.3,$fn=24,center=true);
    translate([cx,cy,0]) cylinder(r=.65,h=1.3,$fn=24,center=true);
  }
}

module EFlink() {
  difference() {
     union() {
       color([.3,.3,.4,.9]) {
         translate([   2,0,0]) cube([7,3,2],center=true);
         translate([EF-2,0,0]) cube([7,3,2],center=true);
       }
       translate([EF/2,0,0]) cube([EF-6,2.6,2.6],center=true);
     }

     #translate([EF,0,0]) cylinder(r=.4,h=3,center=true);
     #                    cylinder(r=.4,h=5,center=true);
  }
}

module EFlink1(ex=0,ey=0,fx=EF,fy=0) {
echo("EF",ex,ey,fx,fy);
  difference() {
     union() {
       color([.3,.3,.4,.9]) {
         translate([ex,ey,0]) cube([4,3,2],center=true);
         translate([fx,fy,0]) cube([4,3,2],center=true);
       }
       hull() {
         translate([ex,ey,0]) cylinder(r=1.3,h=2.6,center=true);
         translate([fx,fy,0]) cylinder(r=1.3,h=2.6,center=true);
       }
     }

     translate([ex,ey,0]) cylinder(r=.7,h=3,center=true);
     translate([fx,fy,0]) cylinder(r=.7,h=3,center=true);
  }
}

// this link drawn with B axle at origin, always.
module BHlinks() {
  difference() {
    translate([0,0,2.4]) cylinder(r=1.4,h=13.5,$fn=36,center=true);
    translate([0,0,2.4]) cube([4,4,7.9],center=true);
  }

  for(z=[-2.4,7.2]) {
     hull() {
       translate([BH-3,0,z]) sphere(.8);
       translate([   0,0,z]) sphere(.8);
     }
  }

  hull() {
    translate([   4,0.5,-2.4]) sphere(.8);
    translate([BH-5,1, 6  ]) sphere(.8);
  }
  hull() {
    translate([   4,-.5, 7]) sphere(.8);
    translate([BH-5, -1, -2  ]) sphere(.8);
  }

  for(z=[-1.7,6.2]) translate([BH,0,z]) difference() {
     hull() {
       cylinder(r=3,h=.33,$fn=36);
       translate([-8,0,0]) cylinder(r=1,h=.33);
     }
     cylinder(r=.7,h=2,center=true);
  }

}
module BHlinks1() {
  translate([0,0, 6.8])                 BHlink();
  translate([0,0,-2  ]) mirror([0,0,1]) BHlink();
}
module BHlink() {
  cylinder(r=1.4,h=6,$fn=24);

  //%translate([BH/2-1,0,1.3]) cube([BH-2,2.5,2.5],center=true);
  for (q=[-1,1]) hull() {
    translate([  0 ,1.5*q,1]) sphere(0.8);
    translate([BH-3,1  *q,1]) sphere(0.8);
  }
  hull() {
    translate([  0 ,0,5]) sphere(0.8);
    translate([BH-3,0,1]) sphere(0.8);
  }

  translate([BH,0,-.3]) difference() {
     hull() {
       cylinder(r=3,h=.33,$fn=36);
       translate([-8,0,0]) cylinder(r=1,h=.33);
     }
     cylinder(r=.7,h=2,center=true);
  }
}


removed old model leftovers

removed old model leftovers


walls are now 2x thicker and height is rounded


triangle-shapped spoon

triangle-shapped spoon

module halfSphere(r)
{
  difference()
  {
    sphere(r);
    d=r+1;
    translate([-d, -d, -d])
      cube([2*d, 2*d, d]);
  }
}

r=17.743;
difference()
{
  halfSphere(19);
  halfSphere(r);
}
translate([-15/2, +r-1, 0])
  cube([15, 140, 5]);