OpenSCAD source code: 3D printed fittings for framework over garden seedlings
// Mesh Shelter Frame for outdoor sprouts | |
// Ed Nisley KE4ZNU - July 2020 | |
/* [Layout Options] */ | |
Layout = "Show"; // [Build, Show, Corner, CornerSet, Base, BaseSet] | |
//------- | |
//- Extrusion parameters must match reality! | |
// Print with 2 shells | |
/* [Hidden] */ | |
ThreadThick = 0.25; | |
ThreadWidth = 0.40; | |
HoleFinagle = 0.2; | |
HoleFudge = 1.00; | |
function HoleAdjust(Diameter) = HoleFudge*Diameter + HoleFinagle; | |
Protrusion = 0.1; // make holes end cleanly | |
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit); | |
inch = 25.4; | |
//------- | |
// Dimensions | |
RodOD = 5.0; | |
SocketDepth = 3*RodOD; | |
WallThick = 3.0; | |
ArmOD = RodOD + 2*WallThick; | |
ArmRadius = ArmOD / 2; | |
SocketSides = 3*4; | |
ArmOC = SocketDepth + ArmOD; // rod entry to corner centerline | |
ArmOAL = ArmOC + ArmRadius; // total arm length to outer edge | |
echo(str("ArmOC: ",ArmOC)); | |
echo(str("ArmOAL: ",ArmOAL)); | |
Nadir = [0,0,-1]; // vector toward print platform | |
RodLength = 100; // just for show | |
//------- | |
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes | |
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2); | |
FixDia = Dia / cos(180/Sides); | |
cylinder(r=HoleAdjust(FixDia)/2,h=Height,$fn=Sides); | |
} | |
//------- | |
BaseVector = [1,1,1]; // vector through middle of base surface | |
module Corner() { | |
difference() { | |
hull() { | |
scale([1/cos(180/SocketSides),1/cos(180/SocketSides),1]) | |
rotate(180/SocketSides) | |
sphere(d=ArmOD,$fn=SocketSides); | |
rotate(180/SocketSides) | |
cylinder(d=ArmOD,h=ArmOC,$fn=SocketSides); | |
rotate([-90,0,0]) rotate(180/SocketSides) | |
cylinder(d=ArmOD,h=ArmOC,$fn=SocketSides); | |
rotate([0,90,0]) rotate(180/SocketSides) | |
cylinder(d=ArmOD,h=ArmOC,$fn=SocketSides); | |
} | |
rotate(180/SocketSides) | |
translate([0,0,ArmOD]) | |
PolyCyl(RodOD,SocketDepth + Protrusion,SocketSides); | |
rotate([-90,0,0]) rotate(180/SocketSides) | |
translate([0,0,ArmOD]) | |
PolyCyl(RodOD,SocketDepth + Protrusion,SocketSides); | |
rotate([0,90,0]) rotate(180/SocketSides) | |
translate([0,0,ArmOD]) | |
PolyCyl(RodOD,SocketDepth + Protrusion,SocketSides); | |
} | |
} | |
module CornerSet(s=RodLength) { | |
translate([-s/2,-s/2,s]) | |
mirror([0,0,1]) | |
Corner(); | |
translate([s/2,-s/2,s]) | |
rotate([0,0,90]) mirror([0,0,1]) | |
Corner(); | |
translate([s/2,s/2,s]) | |
rotate([0,0,180]) mirror([0,0,1]) | |
Corner(); | |
translate([-s/2,s/2,s]) | |
rotate([0,0,-90]) mirror([0,0,1]) | |
Corner(); | |
} | |
module Base() { | |
difference() { | |
union() { | |
cylinder(d=ArmOD,h=ArmOAL/2,$fn=SocketSides); | |
resize([0,0,ArmOC/2]) | |
sphere(d=ArmOC,$fn=2*SocketSides); | |
} | |
translate([0,0,3*ThreadThick]) | |
PolyCyl(RodOD,ArmOAL,SocketSides); | |
translate([0,0,-SocketDepth]) // cut sphere below platform | |
cube(2*SocketDepth,center=true); | |
} | |
} | |
module BaseSet(s=RodLength) { | |
for (i=[-1,1], j=[-1,1]) | |
translate([i*s/2,j*s/2,0]) | |
Base(); | |
} | |
//------- | |
// Build it! | |
if (Layout == "Corner") | |
Corner(); | |
if (Layout == "CornerSet") | |
CornerSet(); | |
if (Layout == "Base") | |
Base(); | |
if (Layout == "BaseSet") | |
BaseSet(); | |
if (Layout == "Show") { | |
CornerSet(); | |
for (i=[-1,1]) | |
translate([i*RodLength/2,RodLength/2,RodLength]) | |
rotate([90,0,0]) | |
color("Green",0.5) | |
cylinder(d=RodOD,h=RodLength,$fn=SocketSides); | |
for (j=[-1,1]) | |
translate([RodLength/2,j*RodLength/2,RodLength]) | |
rotate([0,-90,0]) | |
color("Green",0.5) | |
cylinder(d=RodOD,h=RodLength,$fn=SocketSides); | |
BaseSet(); | |
for (i=[-1,1], j=[-1,1]) | |
translate([i*RodLength/2,j*RodLength/2,0]) | |
color("Green",0.5) | |
cylinder(d=RodOD,h=RodLength,$fn=SocketSides); | |
} | |
if (Layout == "Build") { | |
Finagle = 0.18; // hack for hull's angled round-to-polygon approximations, I think | |
difference() { // slice sliver from base to sit flat on platform | |
union() | |
for (a=[45:90:360]) | |
rotate(a) // distribute around origin | |
translate([ArmOAL,0, // raise base to just below platform level | |
ArmOC/sqrt(3) + (ArmRadius/cos(180/SocketSides))*cos(atan(sqrt(3)/2)) + Finagle]) | |
rotate(17) // arbitrary rotation for tidy arrangement | |
rotate(acos((BaseVector*Nadir)/(norm(BaseVector)*norm(Nadir))), | |
v=cross(BaseVector,Nadir)) // aim belly side downward | |
Corner(); | |
translate([0,0,-ArmOD/2]) // slicing block below platform | |
cube([6*ArmOAL,6*ArmOAL,ArmOD],center=true); | |
} | |
rotate(45) | |
for (i=[-1,1], j=[-1,1]) | |
translate([i*1.5*ArmOC,j*1.5*ArmOC,0]) | |
Base(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
More details on [my blog[(https://softsolder.com/) at https://wp.me/poZKh-9hH