Unmask: Socially enhanced PPE design
transparent area in front of mouth to unmask mouth mimicry.
Extended filter area on rear part of cheeks to makeup for lost area.
{
//
for (i = [-1: 0.01: 3])
color("gray") hull() {
translate([jsin(10 * i * 360) * 0.1, 0, 0])
translate([i * 2, min(i, 0) * -12, 0]) rotate([max(i, 0) * 360, 0, 0])
translate([0, 0, 2]) cube([2 - 0.1, 0.01, 0.001], center = true);
j = i + 0.01;
translate([jsin(10 * j * 360) * 0.1, 0, 0])
translate([j * 2, min(j, 0) * -12, 0]) rotate([max(j, 0) * 360, 0, 0])
translate([0, 0, 2]) cube([2 - .1, 0.01, 0.001], center = true);
}
// uncut stainless
color("gray") translate([-0.17, 1, 0] * 0.22)
translate([0, 0, 2])
linear_extrude(0.002)
polygon([
[-3, 12],
[-1, 12],
[0, 6],
[-2, 6]
]);
// final rocket trunk
translate([4, 0, 0]) color([0.6, 0.6, 0.6]) rotate([0, 90, 0])
linear_extrude(13) difference() {
$fn = 120;
circle(2 - 0.001);
circle(2 - 0.002);
}
$fn = 120;
// laser cutter profile edges
color([0.4, 0.5, 0.7]) translate([-1.8, 12] * 0.5) translate([0, 0, 2])
cube([2.4, 0.5, 1], center = true);
// coil
color([0.6, 0.6, 0.6]) translate([-2, 12] * 1.025) translate([0, 0, 1])
rotate([0, 0, 7]) rotate([0, 90, 0]) cylinder(2, 1, 1, center = true);
// xray and heat treat
color("red") rotate([30, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
color("orange") rotate([50, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
color("gold") rotate([60, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
color("blue") rotate([90, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
//welder
color("yellow") rotate([1, 0, 0]) translate([1, 0, 2]) cube([.125, 0.125, 1.5], center = true);
color([1, .8, .3]) rotate([1, 0, 0]) translate([1, 0, 2]) cube([.4, 0.4, .25], center = true);
}
function jsin(s) =
max(clamp(sin(s + 60) * 3, -0.5, 0.5), clamp(sin(s) * 3, -0.5, 0.5));
function clamp(a, b, c) = min(max(a, min(b, c)), max(b, c));
A padlock that opens with a large number of keys
but also records the unique number of last key to unlock.
This function is useful in shared resources with
many users as it brings accountability and transparency.
rotate([-60,0,0])difference(){
rotate([0,-90,0])rotate_extrude($fn=30)mirror([1,1])intersection (){
hull(){
translate([2,0])square([60,2]);
square([0.01,0.051]);}
offset(-2,$fn=20){offset(2)
union(){
hull(){
square([1,.4]);
translate([40,-59.6])circle(60,$fn=160);
}
translate([3.5,-13.2])circle(14,$fn=160);
}} }
translate([3.25,0])scale([6,1,1])rotate([-90,0,0])cylinder(5,0.4,0.4,center=true,$fn=20);
translate([3.5,1.4])scale([5,1,4])rotate([-0,0,0])sphere(1 , $fn=30);
translate([3.5,-1.4])scale([5,1,4])rotate([-0,0,0])sphere(1 , $fn=30);
translate([2.5,1.8])scale([6,1.7,0.7])rotate([-0,0,0])sphere(1 , $fn=30);
translate([2.5,-1.8])scale([6,1.7,0.7])rotate([-0,0,0])sphere(1 , $fn=30);
}
cover=polyRound([[0,0,0],[7,0,2],[7,5,0],[0,5,0]],8);
finext=polyRound([[0,5,0],[7,5.01,0.5],[7,11.8,0.5],
[6,11.8,0.2],[6,12,0],[0,12,0]],8);
case=polyRound([[0,0,0.01],[6,0.01,0.7],[6,12,0.1],
[5.9,12.8,0],[5.5,13.5,0.1],
[3.5,13.5,0.05],[3.5,13,0.05],[2.5,13,.05],
[2.5,14,0.05],[0,14,0] ],1);
rotate( 90,[0,1,0]){
color("darkred")translate([0,0,-0.1])
rotate_extrude($fn=45)polygon (cover);
color("lightgreen")
intersection(){
rotate_extrude($fn=45)polygon (finext);
translate([0,0,1])linear_extrude(13,convexity=27)
offset(-0.2,$fn=8)offset(0.3,$fn=8)offset(-0.1,$fn=8)
union()
{
circle(5.95,$fn=30);
rotate( 90 ){
translate ([0,0,0])square([0.3,14,],center=true);
translate ([1.5*1,0,0])square([0.3,13.6,],center=true);
translate ([1.5*2,0,0])square([0.3,12.5,],center=true);
translate ([1.5*-1,0,0])square([0.3,13.6,],center=true);
translate ([1.5*-2,0,0])square([0.3,12.5,],center=true);
}
rotate( 0 ){
translate ([0,0,0])square([0.3,14,],center=true);
translate ([1.5*1,0,0])square([0.3,13.6,],center=true);
translate ([1.5*2,0,0])square([0.3,12.5,],center=true);
translate ([1.5*-1,0,0])square([0.3,13.6,],center=true);
translate ([1.5*-2,0,0])square([0.3,12.5,],center=true);
}
}
}
color("lightgreen")rotate_extrude($fn=45)polygon (case);
color("grey")cylinder(18,0.8,0.8,$fn=20);
color("lightgreen")rotate(0)translate([0,0,13])
cube([7,0.5,1],center=true);
color("lightgreen")rotate(60)translate([0,0,13])
cube([7,0.5,1],center=true);
color("lightgreen")rotate(120)translate([0,0,13])
cube([7,0.5,1],center=true);
color("lightgreen")translate([0,0,11.3])
linear_extrude(1,convexity=27)
offset(-0.2,$fn=8)offset(0.3,$fn=8)offset(-0.1,$fn=8)
union()
{
circle(5.95,$fn=30);
color("lightgreen")rotate(45) square([14.5,1.5 ],center=true);
color("lightgreen")rotate(90+45) square([14.5,1.5 ],center=true);
}
color("lightgreen")translate([0,0,5])
linear_extrude(7.3,convexity=27)
offset(0.2,$fn=8)offset(-0.4,$fn=8)
union()
{
circle(5.95,$fn=30);
color("lightgreen")rotate(45) square([14.5,1.5 ],center=true);
color("lightgreen")rotate(90+45) square([14.5,1.5 ],center=true);
}
color("lightgreen")rotate(90+45)translate([6.5,0,11.8])
cylinder(1,0.6,0.6, $fn=6);
color("lightgreen")rotate(90*2+45)translate([6.5,0,11.8])
cylinder(1,0.6,0.6, $fn=6);
color("lightgreen")rotate(90*3+45)translate([6.5,0,11.8])
cylinder(1,0.6,0.6, $fn=6);
color("lightgreen")rotate(90*4+45)translate([6.5,0,11.8])
cylinder(1,0.6,0.6, $fn=6);
}
intersection()
{
translate([0,0,-10]) linear_extrude(15,convexity=27)
difference(){offset(-0.5,$fn=16)offset(1,$fn=8)offset(-0.5,$fn=16)
union(){
translate([8,6])
offset(-0.5,$fn=16)offset(1,$fn=8)offset(-0.5,$fn=16)
square([6,5],center=true);
translate([8,-6])
offset(-0.5,$fn=16)offset(1,$fn=8)offset(-0.5,$fn=16)
square([6,5],center=true);
translate([8,0]) square([3,8],center=true);
}
translate([9.5,5.3]) circle(0.6,$fn=16);
translate([6.5,5.3]) circle(0.6,$fn=16);
translate([9.5,-5.3]) circle(0.6,$fn=16);
translate([6.5,-5.3]) circle(0.6,$fn=16);
}
rotate( 90,[0,1,0]){
color("lightgreen")translate([0,0,5])linear_extrude(6.3,convexity=27)
difference(){
offset(-0.5,$fn=16)offset(1,$fn=8)offset(-0.5,$fn=16)union()
{
circle(5.95,$fn=30);
translate([6,0]) square([5,15],center=true);
}
offset(0.9,$fn=16)offset(-1.5,$fn=16)color("lightgreen") translate([6,0]) square([5,15],center=true);
}
}}
function polyRound(radiipoints,fn=5)=
// reworte most of it all here heavily use of wrap function
let(p=getpoints(radiipoints))
let(r=getradii(radiipoints))
let(Lp1=last(p),Lp=Lp1+1)
let(temp=[for(i=[0:last(p)])
round3points(
p[wrap(i-1,Lp,0)],
p[wrap(i ,Lp,0)],
p[wrap(i+1,Lp,0)],
r[wrap(i,Lp,0)],
fn)
]
)
//common trick to flatten a list of list
[for (a = temp)
for (b = a) b];
function a3DpolyRound(radiipoints,fn=5)=
// reworte most of it all here heavily use of wrap function
let(p=get3points(radiipoints))
let(r=get3radii(radiipoints))
let(Lp1=last(p),Lp=Lp1+1)
let(
temp=[for(i=[0:last(p)])
a3Dround3points(
p[wrap(i-1,Lp,0)],
p[wrap(i ,Lp,0)],
p[wrap(i+1,Lp,0)],
r[wrap(i,Lp,0)],
fn)])
//common trick to flatten a list of list
[for (a = temp)
for (b = a) b];
function angle (a,b)= (atan2(norm(cross(a,b)),a*b));
function a3Dround3points(p1,p2,p3,r,fn)=
let(
p12=p1-p2,
p32=p3-p2,
m12=norm(p12),
m32=norm(p32),
angle123= ( angle( (p12), (p32))),
a=[m12,0],
b=[0,0],
c=[sin(angle123)*m32,cos(angle123)*m32],
temp= round3points(a,b,c,r,fn)
,e=echo(a,c,angle123,r)
)
[
for (l = temp)
p2
+ (l.x * c.y + l.y * -c.x )*(1/(a.x*c.y-c.x*a.y)) * (p12)
+ (l.x * -a.y + l.y * a.x )*(1/(a.x*c.y-c.x*a.y)) * (p32)
]
;
function rot(p,a)=[
p.x*cos(a)-p.y*sin(a),
p.x*sin(a)+p.y*cos(a),0];
function round3points(p1,p2,p3,r,fn)=
// move check to top, single point reurn in case of collinear
dot(un(p1-p2),(p2-p3))>0.98||r==0?[ p2 ]
:
let(ang= (cosineRuleAngle(p1,p2,p3)) )//angle between the lines
// constrained tangD to the shortest leg p1-p2, or p2-p3
let(tangD=min(norm(p1-p2)/2 ,norm(p2-p3)/2, r/tan(ang/2)))
//distance to the tangent point from p2
let(circD=r/sin(ang/2))//distance to the circle centre from p2
let(a12=abs(atan(getGradient(p1,p2))))//angle of line 1
let(a23=abs(atan(getGradient(p2,p3))))//angle of line 2
let(vec21=p1-p2)//vector from p2 to p1
let(vec23=p3-p2)//vector from p2 to p3
let(dir21x=vec21[0]==0?0:vec21[0]/abs(vec21[0]))
//tangent along line p2 to p1 x polerisation. Returns 1,-1 or 0
let(dir21y=vec21[1]==0?0:vec21[1]/abs(vec21[1]))
//tangent along line p2 to p1 y polerisation. Returns 1,-1 or 0
let(dir23x=vec23[0]==0?0:vec23[0]/abs(vec23[0]))
//tangent along line p3 to p1 x polerisation. Returns 1,-1 or 0
let(dir23y=vec23[1]==0?0:vec23[1]/abs(vec23[1]))
//tangent along line p3 to p1 Y polerisation. Returns 1,-1 or 0
let(t12=[p2[0]+dir21x*cos(a12)*tangD,p2[1]+dir21y*sin(a12)*tangD])//tangent point along line p2 to p2 by offseting from p2
let(t23=[p2[0]+dir23x*cos(a23)*tangD,p2[1]+dir23y*sin(a23)*tangD])//tangent point along line p2 to p3 by offseting from p2
let(vec_=getMidpoint(t12,t23)-p2)//vector from P1 to the midpoint of the two tangents
let(dirx_=vec_[0]==0?0:vec_[0]/abs(vec_[0]))//circle center point x polerisation
let(diry_=vec_[1]==0?0:vec_[1]/abs(vec_[1]))//circle center point y polerisation
let(a_=abs(atan(getGradient(getMidpoint(t12,t23),p2))))//angle of line from tangent midpoints to p2
let(cen=[p2[0]+dirx_*cos(a_)*circD,p2[1]+diry_*sin(a_)*circD])//circle center by offseting from p2
let(e1=(p2[0]-p1[0])*(p2[1]+p1[1]))//edge 1
let(e2=(p3[0]-p2[0])*(p3[1]+p2[1]))//edge 2
let(e3=(p1[0]-p3[0])*(p1[1]+p3[1]))//edge 3
let(CWorCCW=(e1+e2+e3)/abs(e1+e2+e3))//rotation of the three points cw or ccw?
CentreN2PointsArc(t12,t23,cen,CWorCCW,fn);
function CentreN2PointsArc(p1,p2,cen,CWorCCW,fn)=
let(r=pointDist(p1,cen))
let(CircA1=invtan(p1[0]-cen[0],p1[1]-cen[1]))//angle of line 1
let(CircA2=cosineRuleAngle(p2,cen,p1))//angle between the lines
[for(i=[0:fn]) [cos(CircA1+(CircA2/fn)*-i*CWorCCW)*r+cen[0],sin(CircA1+(CircA2/fn)*-i*CWorCCW)*r+cen[1]]];
function invtan(run,rise)=
let(a=abs(atan(rise/run)))
rise==0&&run>0?0:rise>0&&run>0?a:rise>0&&run==0?90:rise>0&&run<0?180-a:rise==0&&run<0?180:rise<0&&run<0?a+180:rise<0&&run==0?270:rise<0&&run>0?360-a:"error";
function cosineRuleAngle(p1,p2,p3)=
let(p12=abs(pointDist(p1,p2)))
let(p13=abs(pointDist(p1,p3)))
let(p23=abs(pointDist(p2,p3)))
acos((sq(p23)+sq(p12)-sq(p13))/(2*p23*p12));
function getIntersect(m1,m2,k1,k2)=
let(x=(k2-k1)/(m1-m2))
let(y=m1*x+k1)
[x,y];
function sq(x)=x*x;
function getGradient(p1,p2)=(p2[1]-p1[1])/(p2[0]-p1[0]);
function getConstant(p,m)=p[1]-m*p[0];
function getMidpoint(p1,p2)=[(p1[0]+p2[0])/2,(p1[1]+p2[1])/2];
function pointDist(p1,p2)=
sqrt(abs(sq(p1[0]-p2[0])+sq(p1[1]-p2[1])));
function zipxyr(a,b)=[for(i=[0:last(a)])[a[i].x,a[i].y,b[i]]];
function getpoints(p)=
[for(i=[0:len(p)-1])[p[i].x,p[i].y ]];
// gets [x,y]list of[x,y,r]list
function getradii(p)=
[for(i=[0:len(p)-1])p[i][2]]; // gets [r]list of[x,y,r]list
function get3points(p)=
[for(i=[0:len(p)-1])[p[i].x,p[i].y,p[i].z]];
// gets [x,y,z]list of[x,y,z,r]list
function get3radii(p)=
[for(i=[0:len(p)-1])p[i][3]]; // gets [r]list of[x,y,r]list
function wrap(x,x_max=1,x_min=0) = (((x - x_min) % (x_max - x_min)) + (x_max - x_min)) % (x_max - x_min) + x_min; // wraps numbers inside boundaries
function dot (a,b)=a*b; // dotproduct is implied in * of vextoes
function last(i)=len(i)-1;// shorthand sugar for len(i)-1
function un(v)=v/max(norm(v),1e-16);// div by zero safe unit normal
difference(){
union(){translate([0,0,10])cube([60,60,14]);
translate([0,0])cube([112,10,14]);
translate([0,50])cube([112,10,14]);
translate([60,0,10])cube([52,60,78]
);
translate([70,0,16])cube([32,110,12]);
translate([52 ,30,88])rotate([0,90,0])cylinder (68,30,30);
hull(){
translate([82,0,16])cube([8,94,24]);
translate([82,0,16])cube([8,60,78]);
translate([82 ,30,88])rotate([0,90,0])cylinder (8,30,30);
}
translate([86 ,110,16])cylinder (24,16,16);
translate([82 ,30,88])rotate([0,90,0])cylinder (8,30,30);
}
translate([86 ,110,15])cylinder (26,8,8);
translate([50 ,30,88])rotate([0,90,0])cylinder (100,16,16);
translate([24 ,30,0]) cylinder (30,9,9);
}
$fn=64;
color("lightgrey")
difference(){
intersection(){
translate([0,-36,0])cube([154,72,100]);
union(){
hull(){
translate([0,-36,0])cube([144,72,20]);
translate([144,-26,0]) cylinder(20,10,10 );
translate([144,26,0]) cylinder(20,10,10 );
}
hull(){
translate([36,0,82])rotate([90,0,0]) cylinder(10,18,18,center=true);
translate([100,0,10])rotate([90,0,0]) cylinder(10,28,28,center=true);
translate([0,-5,0])cube([10,10,20]);
}
hull(){
translate([-5+36,-27,0])cube([10,54,82-28]);
translate([-5+36,-36,0])cube([10,72,20]);
}
translate([-5+36,-27,0])cube([10,54,82]);
translate([36,0,82])rotate([90,0,0]) cylinder(54,18,18,center=true);
translate([100,0,10])rotate([90,0,0]) cylinder(72,28,28,center=true);
translate([125,0,18.5]) cube([6,80,6],center=true);
}
}
translate([36,0,82])rotate([90,0,0]) cylinder(56,9,9,center=true);
translate([100,0,10])rotate([90,0,0]) cylinder(76,18,18,center=true);
translate([72,-40,-1])cube([144,80,11]);
translate([36,0,82]) cylinder(20,1.5,1.5 );
translate([36+18,- 18,-1]) cylinder(30,6,6 );
translate([36+18, 18,-1]) cylinder(30,6,6 );
translate([154, 0,10]) cube([20,20,30] ,center=true);
translate([128.033,0,23])rotate([90,0,0]) cylinder(80,3,3,center=true);
}
difference(){
union(){
translate([0,0,-10])cylinder(80,25,25);
translate([0,0,-10])cylinder(96,17.5,17.5);
intersection(){
linear_extrude(40,convexity=20){
P();
mirror([0,1,0]) P();
}
translate([40,0,20])rotate([90,0,0])
cylinder(90,70,70,center=true,$fn=60);
}
}
translate([0,0,-20])cylinder(120,10,10);
translate([90,0,20])rotate([90,0,0])
cylinder(100,6,6,center=true,$fn=60);
}
module P()
{
polygon([
[0,0],[35,0],[35,15],
[75,15],[75,35],[110,35],
[110,45],[65,45],[65,25],
[25,25],[0,25]]);
}
$Pathdetail=4;
$SphereDetail=20;
union(){
$fn = $SphereDetail;
color("DarkOrange") DrawSmoothLine(FrillsAndUpperBeak );
color("Orange") DrawSmoothLine(BodyBulk );
color("DarkOrange"){
DrawSmoothLine(BeakDetalAndFlank );
mirror() DrawSmoothLine(BeakDetalAndFlank );
}
}
//ListOf [X,Y,Z[ScaleX,ScaleY,ScaleZ]]
FrillsAndUpperBeak= [
[0, 16, 10, [5, 5, 5]],
[0, -2, 13, [10, 10, 10]],
[0, -21, 8, [15, 13, 15]],
[0, -10, 28, [5, 5, 5]],
[0, -6, 53, [6, 8, 5]],
[0, -13, 52, [6, 4, 6.5]],
[0, -16, 46, [5, 5, 5]],
[0, -23.5, 41.5, [11, 5, 4.7]],
[0, -26.9, 41.9, [9.9, 3, 4]],
[0, -31.9, 45.3, [5, 3, 2]]
];
BodyBulk= [
[0, 31, 25, [3.5, 3.5, 3.5]],
[0, 27, 12, [10, 10, 10]],
[0, 16, 0, [15, 18, 16]],
[0, 6, 0, [21, 20, 20]],
[0, -10, 3, [28, 25, 22]],
[0, -10, 16-1, [9, 9, 12]],
[0, -10, 30-1, [8, 10, 8]],
[0, -7, 42-1, [15, 17, 17]],
[0, -20, 38.5-1, [13, 10, 4]],
[0, -28, 39-1, [8, 6, 2]]];
BeakDetalAndFlank=
[[0, -33, 46.5, [1.5, 2.5, 2.5]],
[3, -32.5, 46, [1.5, 2.5, 2.5]],
[6, -30.5, 43, [1.5, 2.5, 2]],
[7.7, -28, 41.6, [2.5, 2.5, 1.5]],
[9, -23, 42, [3, 2, 2]],
[8, -19, 43, [3, 3, 3]],
[8, -16, 46, [2, 2, 2]],
[5, -18, 48, [4, 4, 4]],
[8, -16, 46, [2, 2, 2]],
[0, -6, 46, [2, 2, 2]],
[0, -10, 8, [10, 10, 10]],
[9, -10, 4, [20, 20, 17]],
[7, 0, 3, [19, 20, 18]],
[3, 10, 3, [18, 20, 15]]];
module DrawSmoothLine(ListOfPoints)
{
SmoothedLine=SmoothLine (ListOfPoints);
DrawPolyline( SmoothedLine ) ;
}
function SmoothLine (ListOfPoints)=
let(Steps=(100/$Pathdetail))
[for(t=[0:Steps])
(PiecewiseQuadraticBezierCurve(t/Steps, ListOfPoints) )];
function PiecewiseQuadraticBezierCurve
(PositionAlongPath,ListOfPoints)=
let(
ListLenght=len(ListOfPoints)-1,
PaddedListOfPoints=PadList(ListOfPoints) ,
IndexCenterPoint=
round((ListLenght)*PositionAlongPath)+1, // +One to offset padding
IndexPreviousPoint=IndexCenterPoint-1,
IndexfollowingPoint=IndexCenterPoint+1,
PositionAlongSegment=(((ListLenght)*PositionAlongPath)+0.5)%1 ,
FirstHandle =
FindMidpoint
(PaddedListOfPoints,IndexPreviousPoint,IndexCenterPoint ),
CenterPoint =
PaddedListOfPoints[IndexCenterPoint],
LastHandle =
FindMidpoint
( PaddedListOfPoints, IndexCenterPoint,IndexfollowingPoint) )
QuadraticBezierSegment
(FirstHandle,CenterPoint, LastHandle,PositionAlongSegment ) ;
function PadList(ListOfPoints)=
concat(ExtendOnePointBefore(ListOfPoints),
ListOfPoints,
ExtendOnePointAfter(ListOfPoints) );
function ExtendOnePointBefore(ListOfPoints)=
[ListOfPoints[0]-(ListOfPoints[1]-ListOfPoints[0])];
function ExtendOnePointAfter(ListOfPoints)=
let( ll=len(ListOfPoints)-1 )
[ListOfPoints[ll]-(ListOfPoints[ll-1]-ListOfPoints[ll])];
function FindMidpoint(v,ia,ib)=lerp(v[ia],v[ib],0.5);
function lerp( v1, v2, bias) = (1-bias)*v1 + bias*v2;
function QuadraticBezierSegment
(FirstHandle,CenterPoint, LastHandle,PositionAlongSegment)=
lerp(
lerp( FirstHandle,CenterPoint,PositionAlongSegment),
lerp(CenterPoint,LastHandle,PositionAlongSegment),
PositionAlongSegment)
;
module DrawPolyline(PointList )
{
for(i=[0:len(PointList)-2])
DrawLineSegment(PointList[i],PointList[i+1]);
}
module DrawLineSegment(p1, p2 )
{
color(p1[4])
hull() {
translate(vec3(p1)) scale(p1[3])sphere(1 );
translate(vec3(p2)) scale(p2[3])sphere(1);
}
}
function vec3(v) = [ v.x, v.y, v.z ];
$fn=80;
color("lightgrey")assembly();
module assembly(){
difference( ){
union(){
bell();
fftransform()linear_extrude(11) ffprofile ();
ddtransform() linear_extrude(10)ddprofile();
}
union(){
core();
fftransform()
linear_extrude(23,center=true, convexity = 20)ffnegprofile();
ddtransform()
linear_extrude(23,center=true, convexity = 20)ddnegprofile();
}
}
}
module fftransform(){
translate([0,0,35])
rotate([0,-21,0])
translate([0,0,-20])
rotate([0,90,0])
children() ;}
module ddtransform(){
rotate([0,0,180+45])
translate([0,0,35])
rotate([0,-21,0])
translate([0,0,-20])
rotate([0,90,0])
children() ;}
module bell(){
rotate_extrude( ) offset(-0.1)offset(0.2)offset(-0.1)
polygon(
[
[27.5,0],[27.5,4],[20,4],
[9.5,31],[7.5,31],[7.5,35],
[0,35], [0, 0.0]
]); }
module core(){
rotate_extrude()polygon(
[
[0,36],[5.5,36], [5.5,29],
[8.13, 29], [19.31, 0.0],[0,-1]
]);
}
module ffprofile ()
{
offset(-4)offset(4){circle(8);
translate( [0,10,0])circle(3.25);
translate( [0,-10,0])circle(3.25);}
}
module ffnegprofile ()
{
circle(14/2);
translate( [0,10,0])circle(1.25);
translate( [0,-10,0])circle(1.25);
}
module ddprofile ()
{circle(20/2);}
module ddnegprofile ()
{
circle(12/2);
translate( [0,8,0])circle(1.25);
translate( [0,-8,0])circle(1.25);
translate( [8,0,0])circle(1.25);
translate( [-8,0,0])circle(1.25);
}
$fn=40;
main();
module main(){
translate ([17.5,-25,29])rotate([-90,0,0])insert();
translate ([-17.5,-25,29])rotate([-90,0,0])insert();
difference(){
union(){
rotate([90,0,0])linear_extrude(30,center=true,convexity=20)
bottomprofile1();
rotate([90,0,0])linear_extrude(40,center=true,convexity=20)
bottomprofile2();
translate ([0,0,10]) rotate([90,0,0])
linear_extrude(40,center=true,convexity=20)topprofile2();
translate ([0,0,10]) rotate([90,0,0])
linear_extrude(30,center=true,convexity=20)topprofile1();
}
translate([-30, 7.5,30])cylinder(100,2.25,2.25,center=true);
translate([ 30, 7.5,30])cylinder(100,2.25,2.25,center=true);
translate([ 30,-7.5,30])cylinder(100,2.25,2.25,center=true);
translate([-30,-7.5,30])cylinder(100,2.25,2.25,center=true);
translate([ 0, 15, 30])cylinder(100,2.25,2.25,center=true);
translate([ 0,-15, 30])cylinder(100,2.25,2.25,center=true);
}}
module insert(){ difference()
{color("blue"){
cylinder(5,10,10);
cylinder(45,7.5,7.5);}
translate([0,0,-0.01])cylinder(45.04,5.5,5.5);
}}
module bottomprofile1()
{
difference(){
union(){
polygon([[0,5],[25,5],[20,0],[42.5,0],
[42.5,12.5],[35,15],[35,25],[0,25]]);
mirror()
polygon([[0,5],[25,5],[20,0],[42.5,0],
[42.5,12.5],[35,15],[35,25],[0,25]]);
}
translate ([17.5,25])circle(7.5);
translate ([-17.5,25])circle(7.5);
}}
module bottomprofile2(){
difference(){
union(){intersection(){
square([70,50],center=true);
union(){ hull(){
translate ([17.5,25])circle(12.5);
translate ([-17.5,25])circle(12.5);
}
translate ([0,12.5])square(15,center=true);
}
}
}
translate ([17.5,25])circle(7.5);
translate ([-17.5,25])circle(7.5);
}}
module topprofile1()
{ difference(){translate ([0,25])
hull(){
translate ([0,5.75]) square([70,11.5],center=true);
translate ([0,6.25]) square([68,12.5],center=true);
}
translate ([17.5,25])circle(7.5);
translate ([-17.5,25])circle(7.5);
}
}
module topprofile2(){
difference(){
union(){intersection(){
translate ([0,50]) square([70,50],center=true);
union(){ hull(){
translate ([17.5,25])circle(12.5);
translate ([-17.5,25])circle(12.5);
}
translate ([0,12.5])square(15,center=true);
}
}
}
translate ([17.5,25])circle(7.5);
translate ([-17.5,25])circle(7.5);
}}
main();
module main(){
{
head();
arm();
foot();
}
}
module head()
{
difference(){
union(){
translate([150,-6,38+17])mirror([1,0,1])ocorner(3);//trim
translate([150, 6,38+17])mirror([1,0,1])ocorner(3);//trim
translate([147,-12,38+14+3])cube([7,18+6,27]);//trim
translate([147,-6,38+11])cube([7,18-6,33]);//trim
difference(){
translate([150,-16,38])cube([60,32,44]);
translate([150,0,38+44])mirror([0,0,0])
mirror([0,-1,-1])
otrim(34);//trim
}
}
translate([147,-12,38+11])cylinder(44,3,3);//trim
translate([147,12,38+11])cylinder(44,3,3);//trim
translate([147, 0,38+11]) rotate([90,0,0])
cylinder(44,3,3,center=true);//trim
translate([147,-12,38+44])mirror([0,0,1])
ocorner(3);//trim
translate([147, 12,38+44])mirror([0,0,1])
ocorner(3);//trim
translate([175, 0,38+22])rotate([90,0,0])
cylinder(44,15,15,center=true,$fn=64);//trim
translate([200, 0,38+22])rotate([0,0,0])
cylinder(45,4.5,4.5,center=true,$fn=16);//trim
translate([200, 0,38+22])rotate([0,0,0])
cylinder(2,30,30,center=true,$fn=16);//trim
}
}
module arm()
{
difference(){
translate([70,-9,38+14])cube([80,18,30]);
//trim
translate([110,-9,52])mirror([0,0,1])mirror([1,0,1])otrim(81);
translate([110,9,52])mirror([0,1,-1])mirror([1,0,1])otrim(81);
translate([110,-9,82])mirror([0,0,1])mirror([1,0,-1])otrim(81);
translate([110,9,82])mirror([0,1,1])mirror([1,0,-1])otrim(81);
}
difference(){
translate([20,-9,10])cube([55,18,22]);
//trim
translate([20,-9,15])mirror([0,0,0])otrim(36);
translate([20,9,15])mirror([0,1,0])otrim(36);
translate([75,-9,15])mirror([1,0,0])otrim(36);
translate([75,9,15])mirror([1,1,0])otrim(36);
}
intersection()
{
translate([20,-9,32])cube([75,18,50]);
difference(){ translate([70,0,32]) rotate([90,0,0])
cylinder(18,50,50,center=true,$fn=64);
translate([95,0,32]) rotate([90,0,0])
cylinder(19,20,20,center=true,$fn=64);
//trim
mirror([0,0,0])translate([95,9,32]) rotate([90,0,0])
ocorner32(20);
mirror([0,1,0])translate([95,9,32]) rotate([90,0,0])
ocorner32(20);
mirror([0,1,0])translate([70,9,32]) rotate([90,0,0])
ocorner32(-55+5);
mirror([0,0,0])translate([70,9,32]) rotate([90,0,0])
ocorner32(-55+5);
}
}
}
module foot(){
difference(){
hull(){ for(i=[0:1/4:1]){
y=cos(i*90)*3; x=-3+sin(i*90)*3;
translate([0,0,0]) linear_extrude(7+y) offset( x)footP();
} }
translate([0,0,-0.005])linear_extrude(10.01){
circle(4);
translate([75,-30])circle(4);
translate([75,30]) circle(4);}
}
//trim
translate([20+3,-9+3,10])ocorner(3);
translate([20+3,9-3,10])ocorner(3);
translate([75-3,-9+3,10])ocorner(3);
translate([75-3,9-3,10])ocorner(3);
translate([20,0,10])mirror([1,0,0])mirror([0,-1,1])
otrim(12);
translate([75,0,10]) mirror([0,-1,1])
otrim(12);
translate([20+55/2,9,10])mirror([0,0,1])mirror([1,0,1])
otrim(55-6);
translate([20+55/2,-9,10])mirror([0,-1,1])mirror([1,0,1])
otrim(55-6);}
module footP(){
hull()
{
circle(10);
translate([75,-30])circle(10);
translate([75,30])circle(10);
}
}
module quarterround(){
difference()
{
translate([-1,-1]) square([4,4]);
translate([3,3])circle(3,$fn=16);
}}
module ocorner(r)
{
rotate_extrude ($fn=16,convexity=20)translate([r,0])
quarterround();
}
module ocorner32(r)
{
rotate_extrude ($fn=64,convexity=20)translate([r,0])
quarterround();
}
module otrim(l)
{
linear_extrude (l,center=true,convexity=20)translate([0,0])
quarterround();
}
$fn=50;
main();
module main(){
difference(){
union(c ){
translate([ 0, 0, 80+36])cylinder( 30+6+6,8,8);
linear_extrude(6,convexity=20)plate1();
linear_extrude( 80+36+6,convexity=20)difference(){
square(60,center=true);translate([21.01,0,0])square(42,center=true);}
translate([ 0, 0, 36+6])rotate ([90,0,0])cylinder (60,19,19,center=true);
translate([ 0, 0, 80+36+6])rotate ([90,0,0])cylinder (60,30,30,center=true);
}
translate([ 0, 0, 80+36])cylinder( 30+6+7,4,4);
translate([ 0, 0, 36+6])
linear_extrude( 80+ 30+7,convexity=20)translate([16,0,0])square([32,61],center=true);
translate([ 0, 0, 36+6])rotate ([90,0,0])cylinder (61,7,7,center=true);
translate([ 0, -40, 36+6])rotate ([90,0,0])cylinder (60,12,12,center=true);
translate([ 0, 45, 36+6])rotate ([90,0,0])cylinder (60,12,12,center=true);
translate([ 0, 0, 80+36+6])rotate ([90,0,0])cylinder (61,9,9,center=true);
translate([ 0, -20, 80+36+6])rotate ([90,0,0])cylinder (60,15,15,center=true);
translate([ 0, -40, 80+36+6])rotate ([90,0,0])cylinder (60,20,20,center=true);
}
}
module plate1()
{
center=true;
R=13;r=8;
difference(){
union(){
translate([ 40, 40])circle( R );
translate([-40, 40])circle( R );
translate([-40,-40])circle( R);
translate([ 40,-40])circle( R );
square(80,center);
}
translate([ 40, 40])circle( r );
translate([-40, 40])circle( r );
translate([-40,-40])circle( r );
translate([ 40,-40])circle( r );
}
}

$fn=60;
assembly();
module assembly()
{
rotate([0,-45,0])translate([-225,0,0])flange();
rotate([0,-45,0])translate([-225,0,0])flangerim();
translate([-225,0,0])mirror([0,0,1])flange();
rotate([90,0,0]) pipe();
}
module flange()
{
rotate_extrude()
translate([0,-37]){
hull(){
polygon([[44,0],[112.5,0],[44,37.1]]);
translate([102.5,27])circle(10,$fn=15);
}
fillet([68.5+15,37-0.5],[68.5-1,37],[68.5-1,37+15]);
// fillet is a tiny bit smaller to smooth with the pipe
translate([44,36])square([23.5,15]);
}
}
module flangerim()
{
rotate_extrude()
translate([0,-37]){
translate([44,-10])square([65-44,10]);
}
}
module pipe()
{
rotate_extrude(angle =45,$fn=60, convexity = 20)
translate([-225,0,0])
difference(){
circle(68.5);
circle(44);
}
}
module fillet(a,b,c)
{
difference(){
polygon([a,b,c]);
translate(a+(c-b))circle(norm(a-b),$fn=24);
}}
function flower(r1=100,r2,r3,v1,v2 ,steps=200)=
[ for(t=[0:1/steps:1])
let(
x =r1* sin(t*360) +r2* sin(t*v1*360)+r3* sin(t*v2*360),
y =r1*cos(t*360) +r2*cos(t*v1*360) +r3*cos(t*v2*360) )
[x,y] ];
// function close adds a last point equal yo the first
function close(p)= concat(p,[p[0]]);
function rnd(a = 1, b = 0, s = []) = s == [] ?
(rands(min(a, b), max(
a, b), 1)[0]) : (rands(min(a, b), max(a, b), 1, s)[0]);
function un(v) = v / max(1e-15, norm(v));
color(un([round(rnd(3)) ,round(rnd(3)) *0.75 ,round(rnd(3)) ])) {
paramas=[
70,rnd(30),rnd(15),
round(rnd(3,17))*(round(rnd(-1,1))==1?1:-1),
round(rnd(3,20)*(round(rnd(-1,1))==1?1:-1)) ,300];
echo(paramas);
p=close(flower(paramas[0],paramas[1],paramas[2],
paramas[3],paramas[4],paramas[5],paramas[6]));
polygon(p);
}
