//------------------------------------- // Title: PolyPanel Multiside Multicatch // Version: 1.7.0 // Date: 2019-05-01 // Designer: Steve Cooper // Based on the PolyPanel design by Delvin Montes // https://www.myminifactory.com/object/3d-print-polypanels-snaps-only-89595 //------------------------------------- //Design process //The whole idea was driven off the fact that when creating a cyclinder in openscad you can specify a $fn value that determines //the accurancy of the cyclinder i.e. 3 would give a triangle, 4 a square etc so this can be utilised to create any number sided shape. //The challenge then was to replicate the orignal polypanel catch in openscad so that it matches the original spec by Delvin Montes. //Once this was done it's just simply a case of moving them around to the correct place and throwing some parameters at it for the //shape and number of catches and style you want. //Version History //1.7.0 - Added additionalholeheight parameter to give holes an optional inner depth //1.6.0 - Added option to cut hole in the middle //1.5.0 - Adjusted side length to match 45mm virtual edge //1.4.0 - Added option sidescatchesstep that will determine how many side to step round before doing next catch //1.3.0 - Added option sideswithcatches to limit the number of sides with catches on //1.2.0 - Added option to have a mesh bottom and set mesh density //1.1.0 - Added option for multiple catches per side //1.0.0 - Initial version /* SHAPE Details */ //Number of sides to shape sides=4; //Set piece height to 0 to get it only the depth of catches pieceheight=3; //depth of inner part set to 0 for empty or same or greaterthan pieceheight for full fill insertdepth=1.0; //thickness of the border when you have cut out inside border=5; /* CATCH Details */ //Number of sides with catches sideswithcatches=4; //Catch side step - i.e. how many side to step round before putting on next catch sidescatchesstep=1; //Number of catches per side catchesperside=1; /* MESH Details */ //meshbase meshbase = false; //meshgap meshgap = 4; //meshborder meshborder = 1; /* HOLE Details */ //hole hole = true; //hole radius holeradius = 5; //The rim to add to a hole when you have a mesh bottom holemeshrim = 2; //Additional hole rim height additionalholeheight = 1; //******************************************************** //DON'T CHANGE ANYTHING BELOW HERE OR YOU WILL BREAK THE DESIGN //******************************************************** /* [Hidden] */ insertdepthadj = (insertdepth<=0 || meshbase) ? -0.1:insertdepth; sidestogoto = sideswithcatches*sidescatchesstep; sidestocatch = (sideswithcatches>sides) ? sides:sideswithcatches; //These are set based on original design of polypanel catch cycradius = 2.5; sidelength2=45; //calculate the side length based on the virtual 45mm size sidelength=catchesperside*45-tan((180-(sides-2)*180/sides)/2)*cycradius*2; //Radius of cyclinder required rad=((sidelength)/2)/sin(360/(sides*2)); //echo(Diameter_of_shape_is=rad*2); cyclength = 2.5; catchgap = 5; cutradius = 11.661/2; //radius used to cut catch pinradius = 11.535/2; //radius used to cut pin tolerance=cutradius-pinradius; //Work out some adjustment values for how far curved parts go in and out of main shape adjcatch=cutradius-sqrt(pow(cutradius,2)-pow(cycradius,2)); adjpin=pinradius-sqrt(pow(pinradius,2)-pow(cycradius,2)); //calculate the actual pin length based on the catch gap and the recesses minus the tolerance pinlength = catchgap+2*(adjcatch-tolerance); //overall precision of curves - higher values take longer to render $fn=60; //set the pieceheight to at least cycradius height pheight = max(pieceheight,cycradius); module cup(){ difference(){ hull(){ //rounded pin translate([0,cyclength/2,0]) rotate([90,0,0]) union(){ translate([0,0,-cyclength/2])cylinder(r=cycradius,h=cyclength); translate([0,0,-cyclength/2])sphere(r=cycradius); } //support material translate([-cycradius,0,-cycradius])linear_extrude(height=1) hull(){ polygon(points=[[0,adjcatch],[0,cyclength+cycradius],[cycradius*1.5,adjcatch]]); translate([cycradius,cyclength/2+cycradius-1,0])circle(r=1); } } //remove socket translate([0,-cutradius+adjcatch,0]) sphere(r=cutradius); //put on a chamfer translate([0,adjcatch,0]) rotate([90,0,0]) difference(){ translate([0,0,0])cylinder(r1=8,r2=8,h=4); translate([0,0,-1])cylinder(r1=5.5,r2=0,h=2); } } } module cups(){ //first cup cup(); //second cup translate([0,-catchgap,0])mirror([0,1,0])cup(); } module pin(){ intersection(){ rotate([90,0,0])cylinder(r=cycradius,h=pinlength); translate([0,pinradius-pinlength,0]) sphere(r=pinradius); translate([0,-pinradius,0]) sphere(r=pinradius); } //add support material hull(){ translate([0,-adjpin,0])rotate([90,0,0])cylinder(r=cycradius,h=pinlength-2*adjpin); translate([-cycradius,-pinlength+adjpin,-cycradius])cube([cycradius*1.5,pinlength-2*adjpin,cycradius]); } } module catch(){ //create 2 catches and a pin and position centrally on y axis with x=0 and z=0 //hardcoded offset values taken from fusion360 pin design translate([cycradius,0,cycradius]) union(){ translate([0,cycradius+cyclength+catchgap+0.355,0])cups(); translate([0,-5.425+adjpin,0]) pin(); } } module makeshape(){ catchangle=360/sides; firstangle = (sides%2==0) ? catchangle/2 : 0; offsetl=sqrt(pow(rad,2)-pow((sidelength)/2,2)); //make core shape difference(){ difference(){ cylinder(r=rad,h=pheight,$fn=sides); difference(){ translate([0,0,insertdepthadj])cylinder(r=rad-border,h=pheight-insertdepthadj+0.02,$fn=sides); if (meshbase==true) mesh(); } } //cut a hole if (hole==true){ translate([0,0,-0.01]) cylinder(r=holeradius,h=insertdepth+0.03); } } //add a rim in a holecut if(hole==true){ difference(){ cylinder(r=holeradius+holemeshrim,h=insertdepth+additionalholeheight); translate([0,0,-0.01]) cylinder(r=holeradius,h=insertdepth+0.03+additionalholeheight); } } //Add on the catches for(i=[1:sidescatchesstep:sidestogoto],j=[1:catchesperside]){ rotate([0,0,catchangle*(i-1)+firstangle]) translate([-offsetl,(catchesperside-1)*(sidelength2/2)-(j-1)*sidelength2,0])rotate([0,0,180])catch(); } } module mesh(){ for(i=[-rad:meshgap+meshborder:rad]){ translate([-rad,i,-0.02])cube([rad*2,meshborder,insertdepth+0.03]); translate([i,-rad,-0.02])cube([meshborder,rad*2,insertdepth+0.03]); } } makeshape(); //mesh();