added color coding on assemblies

added color coding on assemblies

// config e
Ay=3.318;
AC=17.5;
Bx=53.83;

loY=-60;  // location of lower brace beams
loX= 10;

zBar=90;

$fn=8;

for (a=[-1,1]) {
  %translate([0,0,(zBar-10)*a]) legProxy();
  %translate([0,0,(zBar+10)*a]) legProxy();
  translate( [0,0, zBar    *a]) color([.2,.2,.8,1]) mainBar();
  #translate([0,0,a*(zBar+20)]) rotate([0,90*(a+1),0]) outerCap();
}
basket();

module basket() {
  for(a=[-1,1]) {
    %translate([Bx*a,0,0]) cylinder(r=1,h=120,$fn=16,center=true); // main axle
    for (b=[-1,1]) translate([Bx*b,0,zBar*a]) {
       color([0,0,1,.6]) translate([0,0,-6*a])
       cylinder(r=1.9,h=60,$fn=16,center=true); // axle

       // axle brace sleves
       translate([0,0,-26*a]) cylinder(r=2.5,h=18,$fn=16,center=true);
    }

    //color([.6,.8,0,1])
    translate([loX*a,loY,0]) difference() {
       cube([2.5,2.5,230],center=true); // lower rails

       // remove center section for wide platform version
       cube([3,3,66],center=true);
    }

    hull() for (b=[-1,1]) translate([ Bx*b, 0 ,71*a]) sphere(1); // arm guard bar
    //hull() for (b=[-1,1]) translate([loX*b,loY,71*a]) sphere(1); // outer foot bar
    for (b=[-1,1]) {
      hull() { // outer diagonal
        translate([ Bx*b, 0 ,70*a]) sphere(1);
        translate([20*b,loY+2,70*a]) sphere(1);
      }
    }

    for(x=[-1,1]) {
       hull() { // inner back trap
         translate([x*35,loY+4,22*a]) sphere(1);
         translate([x*Bx,  0  , 5*a]) sphere(1);
       }
       hull() { // outer back
         translate([x*35,loY+2,31*a]) sphere(1);
         translate([x*Bx,  0  ,60*a]) sphere(1);
       }
    }

    *hull() { // center foot low diag
      translate([ loX,loY, 5*a]) sphere(1);
      translate([-loX,loY,30*a]) sphere(1);
    }
    *hull() {
      translate([-loX,loY,40*a]) sphere(1);
      translate([ loX,loY,70*a]) sphere(1);
    }
    *for (b=[-1,1]) hull() {  // outer low X
      translate([-loX*b,loY,130*a]) sphere(1);
      translate([ loX*b,loY, 70*a]) sphere(1);
    }

    // may do something more complicated for payload bay,
    // but for now, just stich sides together
    translate([a*(Bx+2),2,0]) cube([3.8,3.8,140],center=true);

    translate([34*a,loY+6,0]) cube([2.5,2.5,138],center=true);
    translate([0,loY+3,67*a]) cube([70,3.8 ,3.8],center=true);
  }

  for(z=[-1,0,1]) translate([0,loY+3,34*z])
     cube([70,2.5,2.5],center=true);
  color([0,.2,.8,.2]) // expanded mesh floor
     translate([0,loY+5,0]) cube([68,.5,130],center=true);
     //translate([0,loY+2,0]) cube([2*loX,1,130],center=true);
}

module mainBar() {
  cube([110,5,5],center=true);
  translate([0,Ay,0]) {
    cylinder(r=1.5,h=4,$fn=16,center=true);
    #cylinder(r=AC,h=2,$fn=36,center=true);
    //cylinder(r=AC+2,h=.4,$fn=36,center=true);
  }

  // lower support
  for(x=[-1,1]) {
     // lower rail tubes
     translate([x*loX,loY,0]) cube([3.8,3.8,10],center=true);

     hull() {     // diagonals
       translate([x*(loX+2),loY,0]) sphere(1);
       translate([x*(Bx-8),0,0]) sphere(1);
     }
  }
  translate([0,loY,0]) cube([2*loX,3.8,3.8],center=true);
}

module outerCap() {
  for (b=[-1,1]) translate([Bx*b,0,-1]) {
     // axle brace sleves... shorter on outside
     cylinder(r=2.5,h=6 ,$fn=16,center=true);
  }
  translate([0,loY,0]) cube([2*loX,3.8,3.8],center=true);
  for(x=[-1,1]) translate([x*loX,loY,1])
         cube([3.8,3.8,8],center=true); // lower rail sleves

  for (b=[-1,1]) hull() { // outside diagonal brace
    translate([loX*b,loY,0]) sphere(1);
    translate([ Bx*b, 0 ,0]) sphere(1);
  }
  hull() for(b=[-1,1]) translate([Bx*b,0,0]) sphere(1);
}

module legProxy() scale([1,1,12]) {
  legProxy1();
  mirror([1,0,0]) legProxy1();
}

// measurements from drawing, center pixel 600,300, 4 pixels/cm
module legProxy1() {

  hull() {
    translate([0,3.32,0]) cylinder(r=17.5+2,h=1,$fn=36,center=true);
    translate([-250/4, 290/4,0]) node();
    translate([-200/4, 290/4,0]) node();
    translate([-360/4, 120/4,0]) node();
    translate([-500/4,-110/4,0]) node();
    translate([-430/4,-230/4,0]) node();
  }
  hull() {
    translate([-400/4,-220/4  ,0]) node();
    translate([-340/4,-370/4+2,0]) node();
    translate([ -90/4,-370/4+2,0]) node();
    translate([-140/4,-120/4  ,0]) node();
  }
}

module node() cylinder(r=2,h=1,$fn=9,center=true);

// config e
Ay=3.318;
AC=17.5;
Bx=53.83;

loY=-60;  // location of lower brace beams
loX= 10;

zBar=90;

$fn=8;

for (a=[-1,1]) {
  %translate([0,0,(zBar-10)*a]) legProxy();
  %translate([0,0,(zBar+10)*a]) legProxy();
  translate( [0,0, zBar    *a]) mainBar();
  translate([0,0,a*(zBar+20)]) rotate([0,90*(a+1),0]) outerCap();
}
basket();

module basket() {
  for(a=[-1,1]) {
    %translate([Bx*a,0,0]) cylinder(r=1,h=120,$fn=16,center=true); // main axle
    for (b=[-1,1]) translate([Bx*b,0,zBar*a]) {
       color([0,0,1,1]) translate([0,0,-6*a])
       cylinder(r=1.9,h=60,$fn=16,center=true); // axle

       // axle brace sleves
       translate([0,0,-26*a]) cylinder(r=2.5,h=18,$fn=16,center=true);
    }

    translate([loX*a,loY,0]) {
       color([0,0,1,1]) cube([2.5,2.5,230],center=true); // lower rails
    }

    hull() for (b=[-1,1]) translate([ Bx*b, 0 ,71*a]) sphere(1); // arm guard bar
    //hull() for (b=[-1,1]) translate([loX*b,loY,71*a]) sphere(1); // outer foot bar
    for (b=[-1,1]) {
      hull() { // outer diagonal
        translate([ Bx*b, 0 ,70*a]) sphere(1);
        translate([loX*b,loY,70*a]) sphere(1);
      }
    }

    *hull() { // outer front diag
      translate([loX,loY,68*a]) sphere(1);
      translate([ Bx, 0 ,40*a]) sphere(1);
    }
    for(x=[-1,1]) {
       #hull() { // inner back trap
         translate([x*loX,loY,25*a]) sphere(1);
         translate([x*Bx, 0 , 5*a]) sphere(1);
       }
       hull() { // outer back
         translate([x*loX,loY,35*a]) sphere(1);
         translate([x*Bx , 0 ,60*a]) sphere(1);
       }
    }

    *hull() { // center foot low diag
      translate([ loX,loY, 5*a]) sphere(1);
      translate([-loX,loY,30*a]) sphere(1);
    }
    *hull() {
      translate([-loX,loY,40*a]) sphere(1);
      translate([ loX,loY,70*a]) sphere(1);
    }
    *for (b=[-1,1]) hull() {  // outer low X
      translate([-loX*b,loY,130*a]) sphere(1);
      translate([ loX*b,loY, 70*a]) sphere(1);
    }

    // may do something more complicated for payload bay,
    // but for now, just stich sides together
    translate([a*(Bx+2),2,0]) cube([3.8,3.8,140],center=true);
  }

  // expanded mesh floor
  color([0,.2,.8,.2]) translate([0,loY+2,0]) cube([2*loX,1,130],center=true);
}

module mainBar() {
  cube([110,5,5],center=true);
  translate([0,Ay,0]) {
    cylinder(r=1.5,h=4,$fn=16,center=true);
    #cylinder(r=AC,h=2,$fn=36,center=true);
    //cylinder(r=AC+2,h=.4,$fn=36,center=true);
  }

  // lower support
  for(x=[-1,1]) {
     // lower rail tubes
     translate([x*loX,loY,0]) cube([3.8,3.8,10],center=true);

     hull() {     // diagonals
       translate([x*(loX+2),loY,0]) sphere(1);
       translate([x*(Bx-8),0,0]) sphere(1);
     }
  }
  translate([0,loY,0]) cube([2*loX,3.8,3.8],center=true);
}

module outerCap() {
  for (b=[-1,1]) translate([Bx*b,0,-1]) {
     // axle brace sleves... shorter on outside
     cylinder(r=2.5,h=6 ,$fn=16,center=true);
  }
  translate([0,loY,0]) cube([2*loX,3.8,3.8],center=true);
  for(x=[-1,1]) translate([x*loX,loY,1])
         cube([3.8,3.8,8],center=true); // lower rail sleves

  for (b=[-1,1]) hull() { // outside diagonal brace
    translate([loX*b,loY,0]) sphere(1);
    translate([ Bx*b, 0 ,0]) sphere(1);
  }
  hull() for(b=[-1,1]) translate([Bx*b,0,0]) sphere(1);
}

module legProxy() scale([1,1,12]) {
  legProxy1();
  mirror([1,0,0]) legProxy1();
}

// measurements from drawing, center pixel 600,300, 4 pixels/cm
module legProxy1() {

  hull() {
    translate([0,3.32,0]) cylinder(r=17.5+2,h=1,$fn=36,center=true);
    translate([-250/4, 290/4,0]) node();
    translate([-200/4, 290/4,0]) node();
    translate([-360/4, 120/4,0]) node();
    translate([-500/4,-110/4,0]) node();
    translate([-430/4,-230/4,0]) node();
  }
  hull() {
    translate([-400/4,-220/4  ,0]) node();
    translate([-340/4,-370/4+2,0]) node();
    translate([ -90/4,-370/4+2,0]) node();
    translate([-140/4,-120/4  ,0]) node();
  }
}

module node() cylinder(r=2,h=1,$fn=9,center=true);


Added license

Added license

init_cube_size = 50;
iteration_factor = 0.5;


Update deksiriboza_2.scad

Update deksiriboza_2.scad


Added BMP160 mount model

Added BMP160 mount model

wall=2;
sensor_height=4.5;
sensor_sit_depth=6;
sensor_width=11;
handle_size=20;
wire_d=4;

difference() {
    shape_outline();
    // wire hole
    translate([0,0,-handle_size]) cylinder(h=100, d=wire_d, $fn=20);
    // sensor cavity
    translate([-sensor_width/2,1-sensor_height/2,wall+0.1]) cube([sensor_width, sensor_height, sensor_sit_depth]);
}

module shape_outline() {
    cylinder_d=sensor_width+wall*2;
    cone_multiplier = 1.2;
    union() {
        // Inside vent sensor screw-in
        cylinder(d2=cylinder_d, d1=cylinder_d*cone_multiplier, h=sensor_sit_depth+wall);
        // Outside handle body
        translate([0,0,-handle_size]) cylinder(d2=cylinder_d*cone_multiplier, d1=cylinder_d/cone_multiplier, h=handle_size);
        // Twist grip
        translate([-cylinder_d*cone_multiplier/2,-wall/2,-handle_size]) cube([cylinder_d*cone_multiplier, wall, handle_size]);
    }
}

error: pathspec '3d-models/pressure-sensor-mount/bmp160-mount.scad' did not match any file(s) known to git


tibia flange

tibia flange

for better stability in wheel mode, and general stiffness

module tibia(sl = 23, sw = 12.5){
	difference(){
		//solid parts
		union(){
			hull(){
				//main inner square
				translate([-30,-10,0]) cube([28,20,4]);
				//lower taper
				translate([5,-1.5,0]) cube([2,3,4]);
			}

			//leg
			translate([0,-1.5,0]) cube([40,3,4]);
			//top bar
			translate([-33,-7,0]) cube([6,14,4]);
			//rounded corners
			for (i = [ [-30,7,0],[-30,-7,0] ]){
				translate(i) cylinder(r=3,h=4,$fn=50);
			}
		}
		//servo mounts
		for (i = [ [-3,0,-2],[-31,0,-2] ]){
			translate(i) cylinder(r=1,h=20,$fn=20);
		}
		//hole for servo body
		translate([-17,0,2])  cube([sl,sw,22], center=true);
	}
}

// rounded tibia for rolling on :)
module tibia2(sl = 23, sw = 12.5) {
	wheelThickness = 6;
	or = 70;
	ir = or - wheelThickness;
	flangeW = 12;

	difference(){
		//solid parts
		union(){
			hull(){
				//main inner square
				translate([-30,-10,0]) cube([28,20,4]);
				//lower taper
				translate([5,-1.5,0]) cube([2,3,4]);
			}

			//top bar
			translate([-33,-7,0]) cube([6,14,4]);
			//rounded corners
			for (i = [ [-30,7,0],[-30,-7,0] ]){
				translate(i) cylinder(r=3,h=4,$fn=50);
			}

			// wheel section
			translate([-44, ir - 20,0]) {
				// main section
				rotate([0,0,-80]) {

					// section
					sector3D(r=or, ir=ir, a=160, h=4, center = false, $fn=64);

					//flange
					sector3D(r=or, ir=or-1, a=155, h=flangeW, center = false, $fn=64);

					// add rounded tips to the wheel section
					for (i=[0,1])
						rotate([0,0,i*160])
						translate([or - wheelThickness/2,0,0])
						cylinder(r=3, h=4);
				}

			}

		}
		//servo mounts
		for (i = [ [-3,0,-2],[-31,0,-2] ]){
			translate(i) cylinder(r=1,h=20,$fn=20);
		}
		//hole for servo body
		translate([-17,0,2])  cube([sl,sw,22], center=true);
	}
}

module tibia(sl = 23, sw = 12.5){
	difference(){
		//solid parts
		union(){
			hull(){
				//main inner square
				translate([-30,-10,0]) cube([28,20,4]);
				//lower taper
				translate([5,-1.5,0]) cube([2,3,4]);
			}

			//leg
			translate([0,-1.5,0]) cube([40,3,4]);
			//top bar
			translate([-33,-7,0]) cube([6,14,4]);
			//rounded corners
			for (i = [ [-30,7,0],[-30,-7,0] ]){
				translate(i) cylinder(r=3,h=4,$fn=50);
			}
		}
		//servo mounts
		for (i = [ [-3,0,-2],[-31,0,-2] ]){
			translate(i) cylinder(r=1,h=20,$fn=20);
		}
		//hole for servo body
		translate([-17,0,2])  cube([sl,sw,22], center=true);
	}
}

module tibia2(sl = 23, sw = 12.5) {
	wheelThickness = 6;
	or = 70;
	ir = or - wheelThickness;

	difference(){
		//solid parts
		union(){
			hull(){
				//main inner square
				translate([-30,-10,0]) cube([28,20,4]);
				//lower taper
				translate([5,-1.5,0]) cube([2,3,4]);
			}

			//top bar
			translate([-33,-7,0]) cube([6,14,4]);
			//rounded corners
			for (i = [ [-30,7,0],[-30,-7,0] ]){
				translate(i) cylinder(r=3,h=4,$fn=50);
			}

			// wheel section
			translate([-44, ir - 20,0])
			rotate([0,0,-80]) {

				// section
				sector3D(r=or, ir=ir, a=160, h=4, center = false, $fn=64);

				// add rounded tips to the wheel section
				for (i=[0,1])
					rotate([0,0,i*160])
					translate([or - wheelThickness/2,0,0])
					cylinder(r=3, h=4);
			}

		}
		//servo mounts
		for (i = [ [-3,0,-2],[-31,0,-2] ]){
			translate(i) cylinder(r=1,h=20,$fn=20);
		}
		//hole for servo body
		translate([-17,0,2])  cube([sl,sw,22], center=true);
	}
}


Hinge module (w/o integral pin) first pass

function debugprint(s) = search(s, []);

module chamfered_cube(dims, chamfer) {
    w=dims[0]; l=dims[1]; h=dims[2];
    linear_extrude(height=h,twist=0,center=true) {
        offset(r=chamfer) {
          square([w-chamfer*2,l-chamfer*2], center=true);
        }
    }
}

module pin_hinge(h, radius, pin_radius=1.5, fingers=3) {
    gap=0.75;
    total_gap=(fingers-1)*gap;
    unit_h=(h-total_gap)/fingers;
    $fn=30;
    difference() {
        translate([0,0,unit_h/2]) union() {
            for(i=[0:fingers-1]) {
                // the hinge 'finger' cylinder
                translate([0,0, gap*i+i*unit_h]) cylinder(r=radius, h=unit_h, center=true);
                // the lug for each 'finger'
                if (i%2>0) {
                    translate([radius,radius*0.5-gap,gap*i+i*unit_h]) {
                        #chamfered_cube([radius, radius*1.5, unit_h], 1);
                    }
                } else {
                    translate([-radius,radius*0.5-gap,gap*i+i*unit_h]) {
                        #chamfered_cube([radius, radius*1.5, unit_h], 1);
                    }
                }
            }
        }
        union() {
            chamfer = pin_radius+1;
            // the hole for the pin
            translate([0,0, h/2]) #cylinder(r=pin_radius, h=h, center=true);
            // chamfer the pin hole at each end
            translate([0,0,pin_radius/2]) #cylinder(r1=chamfer, r2=pin_radius, h=pin_radius, center=true);
            translate([0,0,h-pin_radius/2]) #cylinder(r1=pin_radius, r2=chamfer, h=pin_radius, center=true);
        }
    }
    difference() {
        // the wall we attach the hinge lugs to
        translate([0,radius*0.5,h/2]) cube([radius*4-gap*2,radius,h], center=true);
        translate([0,0,h/2]) cylinder(r=radius+gap,h=h, center=true);
    }

}

module horizontal_pin_with_5_fingers(length, radius=3, pin_r=1) {
    translate([0,-length/2,3]) rotate([-90,0,0]) pin_hinge(length, radius, pin_r, 5);
}

// horizontal_pin_with_5_fingers(25);

error: pathspec 'Prototype-UR2/assets/3d/pin-hinge.scad' did not match any file(s) known to git


metric-screw: add thread param

metric-screw: add thread param

include <system.scad>
include <shapes.scad>
include <transforms.scad>
include <misc.scad>

include <metric-thread-data.scad>
include <metric-hexnut-data.scad>
include <metric-knurlnut-data.scad>

use <scad-utils/transformations.scad>

// naive, assume head height is same as thread size (generally true for cap heads)
function get_screw_head_h(thread) = lookup(ThreadSize, thread);
function get_screw_head_d(thread) = 2 * lookup(ThreadSize, thread);

module screw(nut, thread, h=10, tolerance=1.05, head_embed=false, with_nut=true, with_head=true, nut_offset=0, orient=[0,0,1], align=[0,0,0])
{
    nut_thread = get(MHexNutThread, nut);
    thread_ = fallback(thread, nut_thread);
    assert(thread_ != undef, "screw: No nut or thread given");
    /*assert(nut!=undef && thread!=undef && nut_thread != thread_, "screw: Mismatched nut and thread");*/

    head_h = get_screw_head_h(nut);
    nut_h = lookup(MHexNutThickness,nut)*tolerance;
    threadsize = lookup(ThreadSize, thread_);

    s = threadsize*tolerance;
    total_h = h;
    size_align(size=[s, s, total_h], orient=-orient, orient_ref=[0,0,1], align=align)
    {
        translate([0,0,head_embed?-head_h:0])
        {
            if(with_head)
            {
                translate([0,0,h/2+.01])
                screw_head(thread=thread_, orient=[0,0,1], align=[0,0,1]);
            }

            screw_thread(thread=thread_, h=h+.1, tolerance=tolerance, orient=[0,0,1], align=[0,0,0]);

            if(with_nut && nut != undef)
            {
                translate([0,0,-h/2+nut_h+nut_offset+(head_embed?head_h:0)])
                screw_nut(nut=nut, tolerance=tolerance, orient=[0,0,1], align=[0,0,-1]);
            }
        }
    }
}

module screw_cut(nut, thread, h=10, tolerance=1.05, head_embed=false, with_nut=true, nut_cut_h=1000, with_head=true, head_cut_h=1000, nut_offset=0, cut_access=true, orient=[0,0,1], align=[0,0,0])
{
    nut_thread = get(MHexNutThread, nut);
    thread_ = fallback(thread, nut_thread);
    assert(thread_ != undef, "screw_cut: No nut or thread given");
    /*assert(nut!=undef && thread!=undef && nut_thread != thread_, "screw_cut: Mismatched nut and thread");*/

    nut_h = get(MHexNutThickness,nut)*tolerance;
    head_h = get_screw_head_h(thread);
    threadsize = get(ThreadSize, thread_);

    s = threadsize*tolerance;
    total_h = h;
    size_align(size=[s, s, total_h], orient=-orient, orient_ref=[0,0,1], align=align)
    {
        translate([0,0,head_embed?-head_h:0])
        {
            if(with_head)
            {
                translate([0,0,h/2+.01])
                screw_head_cut(thread=thread_, tolerance=1.25, override_h=head_cut_h, align=[0,0,1]);
            }

            screw_thread_cut(thread=thread_, h=h+.1, tolerance=tolerance, orient=[0,0,1], align=[0,0,0]);

            if(with_nut && nut != undef)
            {
                translate([0,0,-h/2+nut_h+nut_offset+(head_embed?head_h:0)])
                screw_nut_cut(nut=nut, tolerance=tolerance, h=nut_cut_h, align=[0,0,-1]);
            }
        }
    }

    if($show_vit)
    {
        %screw(nut=nut, thread=thread, h=h, tolerance=tolerance, head_embed=head_embed, with_nut=with_nut, with_head=with_head, nut_offset=nut_offset, orient=orient, align=align);
    }
}

module screw_thread(thread, h=10, tolerance=1.00, orient=[0,0,1], align=[0,0,0])
{
    assert(thread!=undef, "screw_thread: thread is undef");
    // TODO render thread
    threadsize = lookup(ThreadSize, thread);
    cylindera(d=threadsize, h=h, orient=orient, align=align);
}

module screw_thread_cut(thread, h=10, tolerance=1.05, orient=[0,0,1], align=[0,0,0])
{
    assert(thread!=undef, "screw_thread_cut: thread is undef");
    threadsize = lookup(ThreadSize, thread);
    cylindera(d=threadsize*tolerance, h=h, orient=orient, align=align);
}

module screw_head(thread, tolerance=1.00, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    assert(thread!=undef, "screw_head: thread is undef");

    threadsize = lookup(ThreadSize, thread);
    head_h = get_screw_head_h(thread);
    head_d = get_screw_head_d(thread);
    size_align(size=[head_d, head_d, head_h], orient=orient, align=align)
    difference()
    {
        cylindera(d=head_d, h = fallback(override_h,head_h));
        translate([0,0,head_h/2])
        cylindera(d=threadsize, h = head_d/2);
    }
}

module screw_head_cut(thread, tolerance=1.05, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    assert(thread!=undef, "screw_head_cut: thread is undef");

    threadsize = lookup(ThreadSize, thread);
    head_h = get_screw_head_h(thread);
    head_d = get_screw_head_d(thread)*tolerance;
    size_align(size=[head_d, head_d, head_h], orient=orient, align=align)
    translate([0,0,-head_h/2])
    cylindera(d=head_d, h=fallback(override_h, head_h), align=[0,0,1]);
}

module screw_nut(nut, tolerance=1.00, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    assert(nut!=undef, "screw_nut: nut is undef");

    thickness = lookup(MHexNutThickness,nut)*tolerance;
    d = lookup(MHexNutWidthMin, nut)*tolerance;
    facets = lookup(MHexNutFacets, nut);
    cylindera($fn=lookup(MHexNutFacets, nut), d=d, h=fallback(override_h, thickness), orient=orient, align=align);
}

module screw_nut_cut(nut, tolerance=1.05, h=1000, orient=[0,0,1], align=[0,0,0])
{
    assert(nut!=undef, "screw_nut_cut: nut is undef");

    thickness = lookup(MHexNutThickness,nut)*tolerance;
    d = lookup(MHexNutWidthMin, nut)*tolerance;
    size_align(size=[d,d,thickness], orient=orient, align=align)
    {
        translate([0,0,thickness/2])
        {
            screw_nut(nut, tolerance, orient=[0,0,1], align=[0,0,-1]);
            translate([0,0,-thickness+.01])
            {
                cylindera(d=d*1.1, h=h, orient=[0,0,1], align=[0,0,-1]);
            }
        }
    }
}

module nut_trap_cut(nut, thread, trap_offset=10, screw_l=10*mm, screw_l_extra=2*mm, trap_h=10, trap_axis=[0,-1,0], orient=[0,0,1], align=[0,0,0])
{
    nut_thread = get(MHexNutThread, nut);
    thread_ = fallback(thread, nut_thread);
    assert(thread_ != undef, "nut_trap_cut: No nut or thread given");
    /*assert(nut!=undef && thread!=undef && nut_thread != thread_, "nut_trap_cut: Mismatched nut and thread");*/

    threadsize = lookup(ThreadSize, thread_);
    head_h = get_screw_head_h(thread);
    nut_h = lookup(MHexNutThickness,nut)+.5*mm;

    nut_width_min = lookup(MHexNutWidthMin, nut)+.2*mm;
    nut_width_max = lookup(MHexNutWidthMax, nut)+.2*mm;
    s = nut_width_min;
    total_h = nut_h;

    size_align(size=[s, s, total_h], orient=orient, orient_ref=[0,0,1], align=align)
    {
        translate([0,0,nut_h/2-.1])
        screw_thread_cut(thread=thread_, tolerance=1.1, h=screw_l, orient=[0,0,-1], align=[0,0,1]);

        if(screw_l_extra>0)
        translate([0,0,-nut_h/2+.1])
        screw_thread_cut(thread=thread_, tolerance=1.1, h=screw_l_extra+.1, orient=[0,0,1], align=[0,0,-1]);

        hull()
        {
            orient(-orient)
            stack(dist=trap_h, axis=trap_axis)
            {
                orient(orient)
                cylindera($fn=lookup(MHexNutFacets, nut), d=nut_width_max, h=nut_h, align=[0,0,0]);

                orient(orient)
                cubea(size=[nut_width_min,nut_width_min,nut_h], align=[0,0,0]);
            }
        }

        if($show_vit)
        {
            translate([0,0, screw_l])
            translate([0,0, -nut_h/2])
            %screw(nut=nut, thread=thread, tolerance=1, with_nut=false, orient=[0,0,-1], align=[0,0,-1]);

            %screw_nut(nut=nut, thread=thread, tolerance=1, orient=[0,0,-1], align=[0,0,0]);
        }

    }
}

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

if(false)
{
    nut1 = MHexNutM3;
    nut2 = MHexNutM5;
    nut3 = MKnurlInsertNutM3_3_42;
    nut4 = MKnurlInsertNutM3_5_42;

    /*translate([0,20,0])*/
    /*translate([0,20,0])*/
    /*for(axis1=[0:len(AXES)-1])*/
    /*[>for(axis2=AXES)<]*/
    /*translate(20*AXES[axis1])*/
    /*{*/
        /*ta = v_rotate(90, AXES[axis1])*AXES[axis1];*/
        /*echo(AXES[axis1], ta);*/
        /*nut_trap_cut(nut=nut1, trap_axis=ta, orient=AXES[axis1]);*/
    /*}*/

    /*stack(d=30, axis=[1,0,0])*/
    /*{*/
        /*stack(d=20, axis=[0,1,0])*/
        /*{*/
            /*nut_trap_cut(nut=nut1, trap_axis=[0,0,1], orient=[1,0,0]);*/
            /*nut_trap_cut(nut=nut1, trap_axis=[0,0,1], orient=[-1,0,0]);*/
        /*}*/

        /*stack(d=20, axis=[1,0,0])*/
        /*{*/
            /*nut_trap_cut(nut=nut1, trap_axis=[0,0,1], orient=[0,1,0]);*/

            /*nut_trap_cut(nut=nut1, trap_axis=[0,0,1], orient=[0,-1,0]);*/
        /*}*/
    /*}*/

    box_w = 100;
    box_h = 10;
    box_d = 10;
    o = 10;

    $show_vit = true;
    $fs= 0.5;
    $fa = 4;

    difference()
    {
        cubea([box_w,box_d/2,box_h], align=[1,1,1]);

        test_cuts();
    }
    /*difference()*/
    /*{*/
        /*cubea([box_w,box_d/2,box_h], align=[1,-1,1]);*/

        /*test_cuts();*/
    /*}*/

}

module test_cuts()
{
    union()
    {
        offset = 0;
        /*offset = -5;*/
        translate([0,offset,0])
        translate([5,0,0])
        stack(dist=10,axis=[1,0,0])
        {
            screw_cut(nut=nut1, h=box_h, head_embed=false, orient=[0,0,-1], align=[0,0,1]);
            screw_cut(thread=ThreadM5, h=box_h, head_embed=false, orient=[0,0,-1], align=[0,0,1]);
            screw_cut(nut=nut1, h=box_h, head_embed=false, orient=[0,0,1], align=[0,0,1]);

            screw_cut(nut=nut1, h=box_h*mm, nut_offset=0*mm, head_embed=true, orient=[0,0,-1], align=[0,0,1]);
            screw_cut(nut=nut2, h=box_h*mm, nut_offset=3*mm, head_embed=false, orient=[0,0,-1], align=[0,0,1]);
            screw_cut(nut=nut3, h=box_h, head_embed=false, orient=[0,0,-1], align=[0,0,1]);
            screw_cut(nut=nut4, h=box_h, head_embed=false, orient=[0,0,-1], align=[0,0,1]);

            /*translate([0,5,0])*/
            translate([0,0,box_h/2])
                nut_trap_cut(nut=nut1, h=5, head_embed=false, trap_h=10, trap_axis=[0,-1,0], orient=[0,0,-1], align=[0,0,0]);

            translate([0,0,box_h/2])
                nut_trap_cut(nut=nut1, h=5, head_embed=false, trap_h=10, trap_axis=[0,1,0], orient=[0,0,1], align=[0,0,0]);

            translate([0,0,box_h/2])
                nut_trap_cut(nut=nut1, h=box_d, head_embed=false, trap_h=10, screw_l_extra=2*mm, trap_axis=[0,0,1], orient=[0,1,0], align=[0,0,0]);

            translate([0,0,box_h/2])
                nut_trap_cut(nut=nut1, h=box_d, head_embed=false, trap_h=10, screw_l_extra=2*mm, trap_axis=[0,0,-1], orient=[0,1,0], align=[0,0,0]);
        }
    }
}

include <system.scad>
include <shapes.scad>
include <transforms.scad>
include <misc.scad>

include <metric-thread-data.scad>
include <metric-hexnut-data.scad>
include <metric-knurlnut-data.scad>

use <scad-utils/transformations.scad>

// naive, assume head height is same as thread size (generally true for cap heads)
function get_screw_head_h(nut) = lookup(ThreadSize, nut);
function get_screw_head_d(nut) = 2 * lookup(ThreadSize, nut);

module screw(nut=MHexNutM3, h=10, tolerance=1.05, head_embed=false, with_nut=true, with_head=true, nut_offset=0, orient=[0,0,1], align=[0,0,0])
{
    threadsize = lookup(ThreadSize, nut);
    head_h = get_screw_head_h(nut);
    nut_h = lookup(MHexNutThickness,nut)*tolerance;
    thread = get(MHexNutThread, nut);

    s = threadsize*tolerance;
    total_h = h;
    size_align(size=[s, s, total_h], orient=-orient, orient_ref=[0,0,1], align=align)
    {
        translate([0,0,head_embed?-head_h:0])
        {
            if(with_head)
            {
                translate([0,0,h/2+.01])
                screw_head(nut=nut, orient=[0,0,1], align=[0,0,1]);
            }

            screw_thread(thread=thread, h=h+.1, tolerance=tolerance, orient=[0,0,1], align=[0,0,0]);

            if(with_nut)
            {
                translate([0,0,-h/2+nut_h+nut_offset+(head_embed?head_h:0)])
                screw_nut(nut=nut, tolerance=tolerance, orient=[0,0,1], align=[0,0,-1]);
            }
        }
    }
}

module screw_cut(nut=MHexNutM3, h=10, tolerance=1.05, head_embed=false, with_nut=true, nut_cut_h=1000, with_head=true, head_cut_h=1000, nut_offset=0, cut_access=true, orient=[0,0,1], align=[0,0,0])
{
    threadsize = lookup(ThreadSize, nut);
    head_h = get_screw_head_h(nut);
    nut_h = lookup(MHexNutThickness,nut)*tolerance;
    thread = get(MHexNutThread, nut);

    s = threadsize*tolerance;
    total_h = h;
    size_align(size=[s, s, total_h], orient=-orient, orient_ref=[0,0,1], align=align)
    {
        translate([0,0,head_embed?-head_h:0])
        {
            if(with_head)
            {
                translate([0,0,h/2+.01])
                screw_head_cut(nut=nut, tolerance=1.25, override_h=head_cut_h, align=[0,0,1]);
            }

            screw_thread_cut(thread=thread, h=h+.1, tolerance=tolerance, orient=[0,0,1], align=[0,0,0]);

            if(with_nut)
            {
                translate([0,0,-h/2+nut_h+nut_offset+(head_embed?head_h:0)])
                screw_nut_cut(nut=nut, tolerance=tolerance, h=nut_cut_h, align=[0,0,-1]);
            }
        }
    }

    if($show_vit)
    {
        %screw(nut=nut, h=h, tolerance=tolerance, head_embed=head_embed, with_nut=with_nut, with_head=with_head, nut_offset=nut_offset, orient=orient, align=align);
    }
}

module screw_thread(thread=ThreadM3, h=10, tolerance=1.00, orient=[0,0,1], align=[0,0,0])
{
    // TODO render thread
    threadsize = lookup(ThreadSize, thread[1]);
    cylindera(d=threadsize, h=h, orient=orient, align=align);
}

module screw_thread_cut(thread=ThreadM3, h=10, tolerance=1.05, orient=[0,0,1], align=[0,0,0])
{
    threadsize = lookup(ThreadSize, thread[1]);
    cylindera(d=threadsize*tolerance, h=h, orient=orient, align=align);
}

module screw_head(nut=MHexNutM3, tolerance=1.00, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    threadsize = lookup(ThreadSize, nut);
    head_h = get_screw_head_h(nut);
    head_d = get_screw_head_d(nut);
    size_align(size=[head_d, head_d, head_h], orient=orient, align=align)
    difference()
    {
        cylindera(d=head_d, h = fallback(override_h,head_h));
        translate([0,0,head_h/2])
        cylindera(d=threadsize, h = head_d/2);
    }
}

module screw_head_cut(nut=MHexNutM3, tolerance=1.05, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    threadsize = lookup(ThreadSize, nut);
    head_h = get_screw_head_h(nut);
    head_d = get_screw_head_d(nut)*tolerance;
    size_align(size=[head_d, head_d, head_h], orient=orient, align=align)
    translate([0,0,-head_h/2])
    cylindera(d=head_d, h=fallback(override_h, head_h), align=[0,0,1]);
}

module screw_nut(nut=MHexNutM3, tolerance=1.00, override_h=undef, orient=[0,0,1], align=[0,0,0])
{
    thickness = lookup(MHexNutThickness,nut)*tolerance;
    d = lookup(MHexNutWidthMin, nut)*tolerance;
    facets = lookup(MHexNutFacets, nut);
    cylindera($fn=lookup(MHexNutFacets, nut), d=d, h=fallback(override_h, thickness), orient=orient, align=align);
}

module screw_nut_cut(nut=MHexNutM3, tolerance=1.05, h=1000, orient=[0,0,1], align=[0,0,0])
{
    thickness = lookup(MHexNutThickness,nut)*tolerance;
    d = lookup(MHexNutWidthMin, nut)*tolerance;
    size_align(size=[d,d,thickness], orient=orient, align=align)
    {
        translate([0,0,thickness/2])
        {
            screw_nut(nut, tolerance, orient=[0,0,1], align=[0,0,-1]);
            translate([0,0,-thickness+.01])
            {
                cylindera(d=d*1.1, h=h, orient=[0,0,1], align=[0,0,-1]);
            }
        }
    }
}

module nut_trap_cut(nut=MHexNutM3, trap_offset=10, screw_l=10*mm, screw_l_extra=2*mm, trap_h=10, trap_axis=[0,-1,0], orient=[0,0,1], align=[0,0,0])
{
    threadsize = lookup(ThreadSize, nut);
    head_h = get_screw_head_h(nut);
    nut_h = lookup(MHexNutThickness,nut)+.5*mm;
    thread = get(MHexNutThread, nut);

    nut_width_min = lookup(MHexNutWidthMin, nut)+.2*mm;
    nut_width_max = lookup(MHexNutWidthMax, nut)+.2*mm;
    s = nut_width_min;
    total_h = nut_h;

    size_align(size=[s, s, total_h], orient=orient, orient_ref=[0,0,1], align=align)
    {
        translate([0,0,nut_h/2-.1])
        screw_thread_cut(thread=thread, tolerance=1.1, h=screw_l, orient=[0,0,-1], align=[0,0,1]);

        if(screw_l_extra>0)
        translate([0,0,-nut_h/2+.1])
        screw_thread_cut(thread=thread, tolerance=1.1, h=screw_l_extra+.1, orient=[0,0,1], align=[0,0,-1]);

        hull()
        {
            orient(-orient)
            stack(dist=trap_h, axis=trap_axis)
            {
                orient(orient)
                cylindera($fn=lookup(MHexNutFacets, nut), d=nut_width_max, h=nut_h, align=[0,0,0]);

                orient(orient)
                cubea(size=[nut_width_min,nut_width_min,nut_h], align=[0,0,0]);
            }
        }

        if($show_vit)
        {
            translate([0,0, screw_l])
            translate([0,0, -nut_h/2])
            %screw(nut, tolerance=1, with_nut=false, orient=[0,0,-1], align=[0,0,-1]);

            %screw_nut(nut, tolerance=1, orient=[0,0,-1], align=[0,0,0]);
        }

    }

}

function get(key, dict) =
    let(x= search(MHexNutThread, MHexNutM3))
    dict[x[0]];

if(false)
{
    nut1 = MHexNutM3;
    nut2 = MHexNutM5;
    nut3 = MKnurlInsertNutM3_3_42;
    nut4 = MKnurlInsertNutM3_5_42;

    /*translate([0,20,0])*/
    /*translate([0,20,0])*/
    /*for(axis1=[0:len(AXES)-1])*/
    /*[>for(axis2=AXES)<]*/
    /*translate(20*AXES[axis1])*/
    /*{*/
        /*ta = v_rotate(90, AXES[axis1])*AXES[axis1];*/
        /*echo(AXES[axis1], ta);*/
        /*nut_trap_cut(nut=nut1, trap_axis=ta, orient=AXES[axis1]);*/
    /*}*/

    /*stack(d=30, axis=[1,0,0])*/
    /*{*/
        /*stack(d=20, axis=[0,1,0])*/
        /*{*/
            /*nut_trap_cut(nut=nut1, trap_axis=[0,0,1], orient=[1,0,0]);*/
            /*nut_trap_cut(nut=nut1, trap_axis=[0,0,1], orient=[-1,0,0]);*/
        /*}*/

        /*stack(d=20, axis=[1,0,0])*/
        /*{*/
            /*nut_trap_cut(nut=nut1, trap_axis=[0,0,1], orient=[0,1,0]);*/

            /*nut_trap_cut(nut=nut1, trap_axis=[0,0,1], orient=[0,-1,0]);*/
        /*}*/
    /*}*/

    box_w = 100;
    box_h = 10;
    box_d = 10;
    o = 10;

    /*$show_vit = true;*/
    $fs= 0.5;
    $fa = 4;

    difference()
    {
        cubea([box_w,box_d/2,box_h], align=[1,1,1]);

        test_cuts();
    }
    /*difference()*/
    /*{*/
        /*cubea([box_w,box_d/2,box_h], align=[1,-1,1]);*/

        /*test_cuts();*/
    /*}*/

}

module test_cuts()
{
    union()
    {
        offset = 0;
        /*offset = -5;*/
        translate([0,offset,0])
        translate([5,0,0])
        stack(dist=10,axis=[1,0,0])
        {
            screw_cut(nut=nut1, h=box_h, head_embed=false, orient=[0,0,-1], align=[0,0,1]);
            screw_cut(nut=nut1, h=box_h, head_embed=false, orient=[0,0,1], align=[0,0,1]);

            screw_cut(nut=nut1, h=box_h*mm, nut_offset=0*mm, head_embed=true, orient=[0,0,-1], align=[0,0,1]);
            screw_cut(nut=nut2, h=box_h*mm, nut_offset=3*mm, head_embed=false, orient=[0,0,-1], align=[0,0,1]);
            screw_cut(nut=nut3, h=box_h, head_embed=false, orient=[0,0,-1], align=[0,0,1]);
            screw_cut(nut=nut4, h=box_h, head_embed=false, orient=[0,0,-1], align=[0,0,1]);

            /*translate([0,5,0])*/
            translate([0,0,box_h/2])
                nut_trap_cut(nut=nut1, h=5, head_embed=false, trap_h=10, trap_axis=[0,-1,0], orient=[0,0,-1], align=[0,0,0]);

            translate([0,0,box_h/2])
                nut_trap_cut(nut=nut1, h=5, head_embed=false, trap_h=10, trap_axis=[0,1,0], orient=[0,0,1], align=[0,0,0]);

            translate([0,0,box_h/2])
                nut_trap_cut(nut=nut1, h=box_d, head_embed=false, trap_h=10, screw_l_extra=2*mm, trap_axis=[0,0,1], orient=[0,1,0], align=[0,0,0]);

            translate([0,0,box_h/2])
                nut_trap_cut(nut=nut1, h=box_d, head_embed=false, trap_h=10, screw_l_extra=2*mm, trap_axis=[0,0,-1], orient=[0,1,0], align=[0,0,0]);
        }
    }
}


yaxis/motormount add print module

yaxis/motormount add print module

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

use <thing_libutils/triangles.scad>
include <thing_libutils/attach.scad>
include <config.scad>
include <pulley.scad>

yaxis_motor_mount_conn = [[0,0,+extrusion_size/2+yaxis_motor_offset_z],[1,0,0]];
yaxis_motor_mount_conn_motor = [[+yaxis_motor_offset_x, 0,+extrusion_size/2+yaxis_motor_offset_z],[0,0,1]];

ymotor_w = lookup(NemaSideSize, yaxis_motor);
ymotor_h = lookup(NemaLengthLong, yaxis_motor);
ymotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
ymotor_mount_h = main_lower_dist_z+extrusion_size+yaxis_motor_offset_z;
ymotor_mount_width = ymotor_w+ymotor_mount_thickness*2 + ymotor_mount_thread_dia*8;

yaxis_motor_pulley_h = 17.5*mm;
yaxis_motor_mount_bearing_clamp_offset_z = yaxis_motor_pulley_h;

module yaxis_motor_mount_bearing_clamp(align=[0,0,0])
{
    bearing_d = bearing_625[1];
    bearing_h = bearing_625[2];
    width=ymotor_w+ymotor_mount_thickness;
    depth=ymotor_w+ymotor_mount_thickness*2;
    height=yaxis_motor_mount_bearing_clamp_offset_z;

    /*size_align(size=[width,depth,height], align=align);*/
    difference()
    {
        cubea([width, depth, height], align=[0,0,-1]);

        ymotor_round_d = lookup(NemaRoundExtrusionDiameter, yaxis_motor);

        translate([0,0,.1])
            fncylindera(h=bearing_h*2, d=bearing_d*rod_fit_tolerance, orient=[0,0,1], align=[0,0,-1]);

        // cutout for belt path
        fncylindera(d=bearing_d, h=height*2, orient=[0,0,1], align=[0,0,-1]);
        translate([depth/2, 0, -bearing_h])
            cubea([depth, ymotor_round_d, height-bearing_h+1], align=[0,0,-1]);

        // cut out motor mount holes etc
        screw_dist = lookup(NemaDistanceBetweenMountingHoles, yaxis_motor);
        for(x=[-1,1])
        for(y=[-1,1])
        translate([x*screw_dist/2, y*screw_dist/2, 1])
        fncylindera(h=height, d=3*mm, orient=[0,0,1], align=[0,0,-1]);
    }

    // debug bearing
    %fncylindera(h=bearing_h, d=bearing_d*rod_fit_tolerance, align=[0,0,-1], orient=[0,0,1]);
}

module motor_mount_top(width, depth, height, belt_cutout=true, belt_cutout_orient=[1,0,0], align=[0,0,0])
{
    size_align(size=[width, depth, height], align=align);
    difference()
    {
        cubea([width, depth, height], align=[0,0,1]);

        ymotor_round_d = lookup(NemaRoundExtrusionDiameter, yaxis_motor);

        // cutout for belt path
        fncylindera(d=ymotor_round_d, h=height*2, orient=[0,0,1], align=[0,0,0]);
        translate([0, 0,-1])
            cubea([depth/2, ymotor_round_d, height*2], align=[1,0,1]);

        // cut out motor mount holes etc
        translate([0,0,-1])
            linear_extrude(height+2)
            stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module yaxis_motor_mount(show_motor=false)
{
    difference()
    {
        // top plate
        union()
        {
            translate([0,0,yaxis_motor_offset_z])
            {
                // top plate
                translate([ymotor_mount_thickness,0,extrusion_size/2])
                {
                    /*translate([ymotor_w/2,0,ymotor_mount_thickness_h+yaxis_motor_mount_bearing_clamp_offset_z+1])*/
                        /*yaxis_motor_mount_bearing_clamp(align=[0,0,-1]);*/

                    translate([ymotor_w/2,0,0])
                        motor_mount_top(width=ymotor_w+ymotor_mount_thickness,
                        depth=ymotor_w+ymotor_mount_thickness*2,
                        height=ymotor_mount_thickness_h,
                        belt_cutout=true,
                        belt_cutout_orient=[1,0,0]);
                }

                translate([0,0,extrusion_size/2])
                {
                    difference()
                    {
                        // reinforcement plate between motor and extrusion
                        cubea([ymotor_mount_thickness, ymotor_w+ymotor_mount_thickness*2, ymotor_h], align=[1,0,-1], extrasize=[0,0,ymotor_mount_thickness_h], extrasize_align=[0,0,1]);

                        // cutout for motor cables
                        translate([0,0,-20*mm])
                            cubea([ymotor_mount_thickness*3, 20*mm, ymotor_h], align=[0,0,-1]);
                    }
                }

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

                    translate([0, i*((ymotor_w/2)+ymotor_mount_thickness/2), extrusion_size/2])
                        cubea([ymotor_mount_thickness, ymotor_mount_thickness, ymotor_mount_h], align=[1,0,-1]);
                }
            }

            // top mount plate
            difference()
            {
                cubea([ymotor_mount_thickness, ymotor_mount_width, extrusion_size], align=[1,0,0]);

                for(i=[-1,1])
                    translate([0, i*(ymotor_w/2+ymotor_mount_thread_dia*3), 0])
                        fncylindera(h=ymotor_mount_thickness*3,d=ymotor_mount_thread_dia, orient=[1,0,0]);
            }

            // bottom mount plate
            translate([0,0,-main_lower_dist_z])
            {
                difference()
                {
                    cubea([ymotor_mount_thickness, ymotor_w, extrusion_size], align=[1,0,0]);

                    for(i=[0])
                        translate([0, i*(ymotor_w/2+ymotor_mount_thread_dia*3), 0])
                            fncylindera(h=ymotor_mount_thickness*3,d=ymotor_mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
                }
            }

        }

    }

    if(show_motor)
    {
        attach(yaxis_motor_mount_conn_motor,[[0,0,0],[0,0,0]])
        {
            motor(yaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);

            translate([0,0,8*mm])
                %pulley_2GT2_20T();

        }
    }
}

module print_yaxis_motor_mount()
{
    attach(yaxis_motor_mount_conn_motor,[[0,0,0],[1,0,0]])
    {
        yaxis_motor_mount(show_motor=false);
    }
}

/*yaxis_motor_mount(show_motor=true);*/

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

use <thing_libutils/triangles.scad>
include <thing_libutils/attach.scad>
include <config.scad>
include <pulley.scad>

yaxis_motor_mount_conn = [[0,0,+extrusion_size/2+yaxis_motor_offset_z],[1,0,0]];
yaxis_motor_mount_conn_motor = [[+yaxis_motor_offset_x, 0,+extrusion_size/2+yaxis_motor_offset_z],[0,0,1]];

ymotor_w = lookup(NemaSideSize, yaxis_motor);
ymotor_h = lookup(NemaLengthLong, yaxis_motor);
ymotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
ymotor_mount_h = main_lower_dist_z+extrusion_size+yaxis_motor_offset_z;
ymotor_mount_width = ymotor_w+ymotor_mount_thickness*2 + ymotor_mount_thread_dia*8;

yaxis_motor_pulley_h = 17.5*mm;
yaxis_motor_mount_bearing_clamp_offset_z = yaxis_motor_pulley_h;

module yaxis_motor_mount_bearing_clamp(align=[0,0,0])
{
    bearing_d = bearing_625[1];
    bearing_h = bearing_625[2];
    width=ymotor_w+ymotor_mount_thickness;
    depth=ymotor_w+ymotor_mount_thickness*2;
    height=yaxis_motor_mount_bearing_clamp_offset_z;

    /*size_align(size=[width,depth,height], align=align);*/
    difference()
    {
        cubea([width, depth, height], align=[0,0,-1]);

        ymotor_round_d = lookup(NemaRoundExtrusionDiameter, yaxis_motor);

        translate([0,0,.1])
            fncylindera(h=bearing_h*2, d=bearing_d*rod_fit_tolerance, orient=[0,0,1], align=[0,0,-1]);

        // cutout for belt path
        fncylindera(d=bearing_d, h=height*2, orient=[0,0,1], align=[0,0,-1]);
        translate([depth/2, 0, -bearing_h])
            cubea([depth, ymotor_round_d, height-bearing_h+1], align=[0,0,-1]);

        // cut out motor mount holes etc
        screw_dist = lookup(NemaDistanceBetweenMountingHoles, yaxis_motor);
        for(x=[-1,1])
        for(y=[-1,1])
        translate([x*screw_dist/2, y*screw_dist/2, 1])
        fncylindera(h=height, d=3*mm, orient=[0,0,1], align=[0,0,-1]);
    }

    // debug bearing
    %fncylindera(h=bearing_h, d=bearing_d*rod_fit_tolerance, align=[0,0,-1], orient=[0,0,1]);
}

module motor_mount_top(width, depth, height, belt_cutout=true, belt_cutout_orient=[1,0,0], align=[0,0,0])
{
    size_align(size=[width, depth, height], align=align);
    difference()
    {
        cubea([width, depth, height], align=[0,0,1]);

        ymotor_round_d = lookup(NemaRoundExtrusionDiameter, yaxis_motor);

        // cutout for belt path
        fncylindera(d=ymotor_round_d, h=height*2, orient=[0,0,1], align=[0,0,0]);
        translate([0, 0,-1])
            cubea([depth/2, ymotor_round_d, height*2], align=[1,0,1]);

        // cut out motor mount holes etc
        translate([0,0,-1])
            linear_extrude(height+2)
            stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module yaxis_motor_mount(show_motor=false)
{
    difference()
    {
        // top plate
        union()
        {
            translate([0,0,yaxis_motor_offset_z])
            {
                // top plate
                translate([ymotor_mount_thickness,0,extrusion_size/2])
                {
                    /*translate([ymotor_w/2,0,ymotor_mount_thickness_h+yaxis_motor_mount_bearing_clamp_offset_z+1])*/
                        /*yaxis_motor_mount_bearing_clamp(align=[0,0,-1]);*/

                    translate([ymotor_w/2,0,0])
                        motor_mount_top(width=ymotor_w+ymotor_mount_thickness,
                        depth=ymotor_w+ymotor_mount_thickness*2,
                        height=ymotor_mount_thickness_h,
                        belt_cutout=true,
                        belt_cutout_orient=[1,0,0]);
                }

                translate([0,0,extrusion_size/2])
                {
                    difference()
                    {
                        // reinforcement plate between motor and extrusion
                        cubea([ymotor_mount_thickness, ymotor_w+ymotor_mount_thickness*2, ymotor_h], align=[1,0,-1], extrasize=[0,0,ymotor_mount_thickness_h], extrasize_align=[0,0,1]);

                        // cutout for motor cables
                        translate([0,0,-20*mm])
                            cubea([ymotor_mount_thickness*3, 20*mm, ymotor_h], align=[0,0,-1]);
                    }
                }

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

                    translate([0, i*((ymotor_w/2)+ymotor_mount_thickness/2), extrusion_size/2])
                        cubea([ymotor_mount_thickness, ymotor_mount_thickness, ymotor_mount_h], align=[1,0,-1]);
                }
            }

            // top mount plate
            difference()
            {
                cubea([ymotor_mount_thickness, ymotor_mount_width, extrusion_size], align=[1,0,0]);

                for(i=[-1,1])
                    translate([0, i*(ymotor_w/2+ymotor_mount_thread_dia*3), 0])
                        fncylindera(h=ymotor_mount_thickness*3,d=ymotor_mount_thread_dia, orient=[1,0,0]);
            }

            // bottom mount plate
            translate([0,0,-main_lower_dist_z])
            {
                difference()
                {
                    cubea([ymotor_mount_thickness, ymotor_w, extrusion_size], align=[1,0,0]);

                    for(i=[0])
                        translate([0, i*(ymotor_w/2+ymotor_mount_thread_dia*3), 0])
                            fncylindera(h=ymotor_mount_thickness*3,d=ymotor_mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
                }
            }

        }

    }

    if(show_motor)
    {
        attach(yaxis_motor_mount_conn_motor,[[0,0,0],[0,0,0]])
        {
            motor(yaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);

            translate([0,0,8*mm])
                %pulley_2GT2_20T();

        }
    }
}

/*yaxis_motor_mount(show_motor=true);*/