openjscad-aurora-webapp
269 строк · 11.2 Кб
1// title: Grille
2// author: Joost Nieuwenhuijse
3// license: MIT License
4
5// Here we define the user editable parameters:
6function getParameterDefinitions() {7return [8{ name: 'outerwidth', caption: 'Outer width of grille:', type: 'float', initial: 190 },9{ name: 'outerheight', caption: 'Outer height of grille:', type: 'float', initial: 120 },10{ name: 'outerdepth', caption: 'Outer depth of grille:', type: 'float', initial: 12 },11{ name: 'thickness', caption: 'Wall thickness:', type: 'float', initial: 2.5 },12{ name: 'innerdistance', caption: 'Inner standoff distance:', type: 'float', initial: 2 },13{ name: 'bladescale', caption: 'Relative size of blades (1.0 is default):', type: 'float', initial: 1 },14{ name: 'numdividers', caption: 'Number of vertical dividers:', type: 'int', initial: 2 },15{16name: 'addlooseners',17type: 'choice',18caption: 'Add loops (for easy removal):',19values: [0, 1],20captions: ["No", "Yes"],21initial: 122},23{24name: 'show',25type: 'choice',26caption: 'Show:',27values: ["all", "grille", "holders"],28captions: ["All", "Grille (for printing)", "Holders (for printing)"],29initial: "all"30},31{32name: 'mouseears',33type: 'choice',34caption: 'Add mouse ears:',35values: [0, 1],36captions: ["No", "Yes"],37initial: 138},39{40name: 'quality',41type: 'choice',42caption: 'Quality:',43values: [0, 1],44captions: ["Draft", "Final"],45initial: 046}47];48}
49
50function main(params)51{
52var outerwidth = params.outerwidth;53var outerheight = params.outerheight;54var thickness = params.thickness;55var outerdepth = params.outerdepth;56var innerdistance = params.innerdistance;57var bladescale = params.bladescale;58
59var draft = params.quality != 1;60
61var marginleftright = 21;62var margintopbottom = 15;63var bladedistance = 12 * bladescale;64var frontroundradius = 5;65frontroundradius = Math.max(frontroundradius, thickness+0.2);66var outerroundradius = 3;67outerroundradius = Math.max(outerroundradius, thickness+0.2);68outerdepth = Math.max(outerdepth, outerroundradius);69outerdepth = Math.max(outerdepth, innerdistance+thickness);70var frontextend = innerdistance + bladescale*12 + thickness - outerdepth;71frontextend = Math.max(frontextend, 1.5);72var bladewidth = outerwidth - 2*marginleftright;73var bladesheight = outerheight - 2*margintopbottom;74var numblades = Math.ceil(bladesheight / bladedistance) + 1;75var topnotchsize = new CSG.Vector3D([20, 8, 3]);76var topnotchpos = new CSG.Vector3D([outerwidth/2-thickness - topnotchsize.x/2, outerheight/2-thickness - topnotchsize.y/2, topnotchsize.z/2]);77var bottomnotchsize = new CSG.Vector3D([12, 4, topnotchsize.z]);78var bottomnotchpos = new CSG.Vector3D([outerwidth/2-thickness - 4 - bottomnotchsize.x/2, -outerheight/2+thickness + bottomnotchsize.y/2, bottomnotchsize.z/2]);79
80var roundresolution = draft? 4 : 16;81
82var result = new CSG();83if(params.show != "holders")84{85// build the shell:86var z0plane = CSG.Plane.fromNormalAndPoint([0, 0, -1], [0, 0, 0]);87var outershell = CSG.roundedCube({center: [0,0,0], radius: [outerwidth/2, outerheight/2, outerdepth], roundradius: outerroundradius, resolution: roundresolution});88outershell = outershell.cutByPlane(z0plane);89var innershell = CSG.roundedCube({center: [0,0,0], radius: [outerwidth/2-thickness, outerheight/2-thickness, outerdepth-thickness], roundradius: outerroundradius-thickness, resolution: roundresolution});90innershell = innershell.cutByPlane(z0plane);91var shell = outershell.subtract(innershell);92var frontextendoutershell = CSG.roundedCube({center: [0,0,0], radius: [bladewidth/2+thickness, bladesheight/2+thickness, outerdepth+frontextend+frontroundradius+thickness], roundradius: frontroundradius, resolution: roundresolution});93var frontextendinnershell = CSG.roundedCube({center: [0,0,0], radius: [bladewidth/2, bladesheight/2, outerdepth+frontextend+frontroundradius+thickness+100], roundradius: frontroundradius-thickness, resolution: roundresolution});94frontextendinnershell = frontextendinnershell.cutByPlane(z0plane);95var plane3 = CSG.Plane.fromNormalAndPoint([0, 0, 1], [0, 0, outerdepth+frontextend+100]);96frontextendinnershell = frontextendinnershell.cutByPlane(plane3);97var plane1 = CSG.Plane.fromNormalAndPoint([0, 0, 1], [0, 0, outerdepth+frontextend]);98frontextendoutershell = frontextendoutershell.cutByPlane(plane1);99var plane2 = CSG.Plane.fromNormalAndPoint([0, 0, -1], [0, 0, innerdistance]);100frontextendoutershell = frontextendoutershell.cutByPlane(plane2);101shell = shell.subtract(frontextendinnershell);102var frontextendshell = frontextendoutershell.subtract(frontextendinnershell);103shell = shell.union(frontextendshell);104
105// build a blade:106var curvedpath = CSG.Path2D.arc({107center: [0,0,0],108radius: 15 * bladescale,109startangle: 20,110endangle: 80,111resolution: draft? 8:32112});113var blade = curvedpath.rectangularExtrude(thickness, bladewidth, draft? 4:16, true);114var bladecenter = blade.getBounds()[0].plus(blade.getBounds()[1]).times(0.5);115blade = blade.translate(bladecenter.negated());116blade = blade.rotateY(-90);117blade = blade.translate([0, 0, -blade.getBounds()[0].z+innerdistance]);118var bladesize = blade.getBounds()[1].minus(blade.getBounds()[0]);119
120// add the blades to the shell:121var blades = new CSG();122for(var i = 0; i < numblades; i++)123{124var topy = bladesheight/2 + thickness - i*bladedistance;125var translatedblade = blade.translate([0, topy-bladesize.y/2, 0]);126blades = blades.union(translatedblade);127}128blades = blades.intersect(frontextendinnershell);129var grille = shell;130grille = shell.union(blades);131
132// add the dividers:133var dividers = new CSG();134if(params.numdividers > 0)135{136var w1 = (bladewidth - params.numdividers * thickness)/(params.numdividers+1);137for(var j = 0; j < params.numdividers; j++)138{139var x = -(params.numdividers-1)*(w1+thickness)/2 + j*(w1+thickness);140var z1 = outerdepth+frontextend;141var divider = CSG.cube({center: [x, 0, (z1+innerdistance)/2], radius: [thickness/2, bladesheight/2, (z1-innerdistance)/2]});142dividers = dividers.union(divider);143}144}145grille = grille.union(dividers);146
147// create the notches:148var notches = new CSG();149var topnotch1 = CSG.cube({center: topnotchpos, radius: topnotchsize.times(0.5) });150notches = notches.union(topnotch1);151var topnotch2 = CSG.cube({center: [-topnotchpos.x, topnotchpos.y, topnotchpos.z], radius: topnotchsize.times(0.5) });152notches = notches.union(topnotch2);153var bottomnotch1 = CSG.cube({center: bottomnotchpos, radius: bottomnotchsize.times(0.5) });154notches = notches.union(bottomnotch1);155var bottomnotch2 = CSG.cube({center: [-bottomnotchpos.x, bottomnotchpos.y, bottomnotchpos.z], radius: bottomnotchsize.times(0.5) });156notches = notches.union(bottomnotch2);157notches = notches.intersect(outershell);158grille = grille.union(notches);159result = result.union(grille);160
161// create the looseners:162if(params.addlooseners == 1)163{164var loosenerinnerwidth = 5;165var loosenerinnerheight = 2;166var loosenerdepth = 4;167var loosener = CSG.cube({center: [0, -outerheight/2 - loosenerinnerheight/2, loosenerdepth/2],168radius: [loosenerinnerwidth/2+thickness, loosenerinnerheight/2+thickness, loosenerdepth/2]});169loosener = loosener.subtract(CSG.cube({center: [0, -outerheight/2 - loosenerinnerheight/2, loosenerdepth/2],170radius: [loosenerinnerwidth/2, loosenerinnerheight/2, loosenerdepth/2]}));171var loosenerx = -outerwidth/2 + loosenerinnerwidth/2 + 5 + thickness;172
173var looseners = loosener.translate([loosenerx, 0, 0]);174looseners = looseners.union(loosener.translate([-loosenerx, 0, 0]));175result = result.union(looseners);176}177
178if(params.mouseears == 1)179{180for(var k = 0; k < 4; k++)181{182var xpos=outerwidth/2-10;183var ypos=outerheight/2;184if(k&1) xpos = -xpos;185if(k&2) ypos = -ypos;186var cylinder = CSG.cylinder({start: [xpos, ypos, 0], end: [xpos, ypos, 0.5], radius: 15});187result = result.union(cylinder);188}189for(var m = 0; m < 4; m++)190{191var xpos2=bladewidth/2 + thickness/2;192var ypos2=bladesheight/2 + thickness/2;193if(m&1) xpos2 = -xpos2;194if(m&2) ypos2 = -ypos2;195var cyl1 = CSG.cylinder({start: [xpos2, ypos2, 0], end: [xpos2, ypos2, 0.5], radius: 15});196var cyl2 = CSG.cylinder({start: [xpos2, ypos2, 0], end: [xpos2, ypos2, innerdistance], radius: 5});197result = result.union(cyl1.union(cyl2));198}199}200}201
202if(params.show != "grille")203{204// create the holders:205var holderyoffset = 0.5;206var holderzoffset = 1;207var holderwidth = 10;208var holderthickness = 3;209var holdertopclipheight = 4;210var holderbottomclipheight = 2;211var holderscrewholeradius = 2;212var holderscrewholedistance = 6;213
214var holderx;215if(params.show == "holders")216{217// just the holders:218holderx = holderwidth/2+2;219}220else221{222holderx = bottomnotchpos.x + bottomnotchsize.x/2 - holderwidth/2;223}224var holdery1 = topnotchpos.y - topnotchsize.y/2 - holderyoffset;225var holdery2 = bottomnotchpos.y + bottomnotchsize.y/2 + holderyoffset;226
227var holdery0 = holdery1+holdertopclipheight;228var holdery3 = holdery2-holderbottomclipheight;229var holder = CSG.cube({center: [0, (holdery1 + holdery2)/2 , holderthickness/2],230radius: [holderwidth/2, (holdery1-holdery2)/2, holderthickness/2]});231var d1 = 7;232var holdery1a = holdery1 - d1;233var holdery2a = holdery2 + d1;234var holderz1 = topnotchsize.z + holderzoffset;235var holderz2 = holderz1 + holderthickness;236holder = holder.union(CSG.cube({237center: [0, (holdery1a+holdery1)/2, holderz2/2],238radius: [holderwidth/2, (holdery1-holdery1a)/2, holderz2/2]239}));240holder = holder.union(CSG.cube({241center: [0, (holdery2a+holdery2)/2, holderz2/2],242radius: [holderwidth/2, (holdery2a-holdery2)/2, holderz2/2]243}));244holder = holder.union(CSG.cube({245center: [0, (holdery0+holdery1a)/2, (holderz2+holderz1)/2],246radius: [holderwidth/2, (holdery0-holdery1a)/2, (holderz2-holderz1)/2]247}));248holder = holder.union(CSG.cube({249center: [0, (holdery2a+holdery3)/2, (holderz2+holderz1)/2],250radius: [holderwidth/2, (holdery2a-holdery3)/2, (holderz2-holderz1)/2]251}));252var screwhole = CSG.cylinder({start: [0,0,0], end: [0, 0, holderthickness], radius: holderscrewholeradius, resolution: 16});253holder = holder.subtract(screwhole.translate([0, holdery1a-holderscrewholedistance, 0]));254holder = holder.subtract(screwhole.translate([0, holdery2a+holderscrewholedistance, 0]));255
256holder = holder.setColor(0, 1, 0);257
258var holders = holder.translate([holderx,0,0]);259holders = holders.union(holder.translate([-holderx,0,0]));260if(params.show == "holders")261{262holders = holders.rotateZ(90);263}264
265result = result.union(holders);266}267result = result.rotateZ(90);268return result;269}
270
271