
/*
Creator : Kerem Yollu 
date : 30.06.2021
Description : A simple Cube library with some of the most useful featured. 
	- Simple cube with or without all around roundig with the option of a flat top | keyCubeFull()
	- Simple cube with or without rounded edges with flat top and bottom. | keyCubeRounded()
	- Cube with opening defined by the desired wall thickness, intern and extern rounding radious and with the extra options of flat top and/or flat inside bottom | keyCubeEmpty()
	- Cube wiht onpneing as described before but with an resses defined by his width heigt and rounding radious | keyCubeEmptyWithResses()
*/
	
$fn = 50; 


cubeLenght = 20;
cubeWidht = 20; 
cubeHeight = 40;
cubeRoundingRadious = 1;
cubeWallThickness = 1;
cubeInnerRoudingRadious = 2;
cubeRessesWidth = 1; 
cubeRessesHeight = 2;
cubeRessesRadious = 3;
cubeCentered = false;
cubeFlatTop = true;
cubeFlatInside = true; 

/*
x = Lenght | mm
y = Widht | mm
z = Height | mm
t = Wall Thickness | mm
r = extern rounding radious for minkowski if = 0 the cube exterior will not be rounded | mm
flat = Top Flat | true / flase
ce = Center or not | true / flase
*/
//keyCubeFull(cubeLenght,cubeWidht,cubeHeight,cubeRoundingRadious,cubeFlatTop,cubeCentered);
module keyCubeFull(x, y, z, r, flat = false, ce = true)
{
    if(r>0)
    {
        if (flat)
        {
            difference()
            {
                minkowski()

                {
                    x = x - r*2;
                    y = y - r*2;
                    if(ce)

                    {
                        translate([-x/2,-y/2,-z/2+r])cube([x, y, z+r]);
                    }
                    else

                    {
                        translate([r,r,r])cube([x, y, z]);
                    }
                    sphere(r=r);
                }

                if(ce)
                {
                    translate([-x/2-0.1,-y/2,z/2])cube([x+0.2, y, 3*r]);
                }
                else
                {
                    translate([0-0.1,0,z])cube([x+0.2, y, 2*r]);
                }
            }
        }
        else
        {
            minkowski()
            {
                x = x - r*2;
                y = y - r*2;
                z = z - r*2;

                if(ce)
                {
                    translate([-x/2,-y/2,-z/2])cube([x, y, z]);
                }
                else
                {
                    translate([r,r,r])cube([x, y, z]);
                }
                sphere(r=r);
            }
        }
    }
    else
    {
        cube([x, y, z], center = ce);
    }
}
 
/*
x = Lenght | mm
y = Widht | mm
z = Height | mm
rad = extern rounding radious | mm
ce = Center or not | true / flase
*/
//keyCubeRounded(10,10,4,3,true);
module keyCubeRounded(x,y,z,rad,ce = true)
{
	if(rad > 0)
	{
	    if(ce)
	    {
	        translate([-x/2,-y/2,-z/2])hull()
	        {
	            translate([rad,rad,0])cylinder(r=rad, h=z);
	            translate([x-rad,rad,0])cylinder(r=rad, h=z);
	            translate([rad,y-rad,0])cylinder(r=rad, h=z);
	            translate([x-rad,y-rad,0])cylinder(r=rad, h=z);
	        }
	    }
	    else
	    {
	        hull()
	        {
	            translate([rad,rad,0])cylinder(r=rad, h=z);
	            translate([x-rad,rad,0])cylinder(r=rad, h=z);
	          	translate([rad,y-rad,0])cylinder(r=rad, h=z);
	            translate([x-rad,y-rad,0])cylinder(r=rad, h=z);
	        }
	    }
	}
	else 
	{
		cube([x,y,z], center = ce);		
	}
}

 
/*
x = Lenght | mm
y = Widht | mm
z = Height | mm
t = Wall Thickness | mm
r1 = extern rounding radious for minkowski if = 0 the cube exterior will not be rounded | mm
r2 = intern rounding radious for minkowski if = 0 the cube interior will not be rounded | mm
tFlat = Top Flat | true / flase
iFlat = Inside bottom flat | true / flase
ce = Center or not | true / flase
*/
//keyCubeEmpty(cubeLenght,cubeWidht,cubeHeight,cubeWallThickness,cubeRoundingRadious,cubeInnerRoudingRadious,cubeFlatTop,cubeFlatInside,cubeCentered);
module keyCubeEmpty(x,y,z,t,r1,r2,tFlat = false, Iflat = false, ce = true)
{
    if(t < r1)
    {
        echo("please set wall thickness at least equal to the extern rounding diameter (r1)");
    }
    else
    {
        difference()
        {
            keyCubeFull(x,y,z,r1,tFlat,ce);
            if(ce)
            {
            	if(Iflat){translate([0,0,t])keyCubeRounded(x-t*2,y-t*2,z,r2/2,ce);}
            	else{translate([0,0,t])keyCubeFull(x-t*2,y-t*2,z,r2,false,ce);}
            }
            else
            {
            	if(Iflat){translate([t,t,t])keyCubeRounded(x-t*2,y-t*2,z,r2/2,ce);}
            	else{translate([t,t,t])keyCubeFull(x-t*2,y-t*2,z,r2,false,ce);}
            }
        }
    }
}

/*
x = Lenght | mm
y = Widht | mm
z = Height | mm
t = Wall Thickness | mm
r1 = extern rounding radious for minkowski if = 0 the cube exterior will not be rounded | mm
r2 = intern rounding radious for minkowski if = 0 the cube interior will not be rounded | mm
rsHeigh = Resses height | mm
rsWidth	= Resses Width | mm
rsRad = Resses rounding radious | mm if = 0 the cresses corners will not be rounded
tFlat = Top Flat | true / flase
iFlat = Inside bottom flat | true / flase
ce = Center or not | true / flase
*/
//keyCubeEmptyWithResses(cubeLenght,cubeWidht,cubeHeight,cubeWallThickness,cubeRoundingRadious,cubeInnerRoudingRadious,cubeRessesHeight,cubeRessesWidth,cubeRessesRadious,cubeFlatTop,cubeFlatInside,cubeCentered);
module keyCubeEmptyWithResses(x,y,z,t,r1,r2,rsHeigh,rsWidth,rsRad,tFlat = false, Iflat = false, ce = true)
{
	if(ce)
	{
		difference()
		{
    		keyCubeEmpty(x,y,z,t,r1,r2,tFlat,Iflat,ce);
			translate([0,0,z/2-rsHeigh/2])keyCubeRounded(x-t*2+rsWidth*2,y-t*2+rsWidth*2,rsHeigh,rsRad/2,ce);
		}
	}
	else 
	{
		difference()
		{
			keyCubeEmpty(x,y,z,t,r1,r2,tFlat,Iflat,ce);
			translate([t-rsWidth,t-rsWidth,z-rsHeigh])keyCubeRounded(x-t*2+rsWidth*2,y-t*2+rsWidth*2,rsHeigh,rsRad/2,ce);
		}
	}
}

module keyPolyRounded(a=[0,0,0],b=[1,0,0],c=[1,1,0],d=[0,1,0],height=1,rad=1)
{
    hull()
    {
        translate([a[0]+rad,a[1]+rad,a[2]])cylinder(r=rad, h=height);
        translate([b[0]-rad,b[1]+rad,b[2]])cylinder(r=rad, h=height);
        translate([c[0]-rad,c[1]-rad,c[2]])cylinder(r=rad, h=height);
        translate([d[0]+rad,d[1]-rad,d[2]])cylinder(r=rad, h=height);
    }
}