-
Practical Solid Modeling for 3D Printing with OpenSCAD
I’m teaching an introduction to OpenSCAD for Squidwrench this evening in Highland NY…
To quote from the course description:
This intensive course will bootstrap you into designing solid models of useful objects suitable for production on a 3D printer.
We won’t build anything like this, but it makes a nice showpiece:

Solid Model – Oblique Exploded Top The presentation in PDF form: Practical Solid Modeling for 3D Printing with OpenSCAD – 2013-09-25
I plan on a bunch of learning-by-doing, but, in the event the typing becomes burdensome, here are the OpenSCAD files:
A simplified version of the Dishwasher Rack Protector, minus the support structure:

Dishwasher rack protector – support model // Dishwasher rack protector // Simplified version for OpenSCAD course // Ed Nisley KE4ZNU - July 2013 ThreadThick = 0.25; ThreadWidth = 0.40; Protrusion = 0.1; // make holes end cleanly //------- // Dimensions PinDia = 4.0 + 0.5; // upright pin diameter + clearance PinRadius = PinDia/2; PinOC = 3.4; // bar center to pin center PinTubeLength = 15.0; // length of upright tube along pin BarDia = 4.7 + 0.2; // horizontal bar diameter + clearance BarRadius = BarDia/2; BarTubeLength = 30.0; // length of horizontal half tube along bar TubeWall = 4*ThreadWidth; // wall thickness -- allow for fill motion TubeSides = 4 * 4; // default side count for tubes (in quadrants) $fn = TubeSides; SupportClear = 0.85; // support structure clearance fraction //------- module ShowPegGrid(Space = 10.0,Size = 1.0) { Range = floor(50 / Space); for (x=[-Range:Range]) for (y=[-Range:Range]) translate([x*Space,y*Space,Size/2]) %cube(Size,center=true); } //------- // Put it together module Protector() { difference() { union() { translate([0,PinOC,0]) rotate(180/TubeSides) cylinder(r=(PinDia + 2*TubeWall)/2,h=PinTubeLength); translate([-BarTubeLength/2,0,0]) rotate([0,90,0]) rotate(180/TubeSides) cylinder(r=(BarDia + 2*TubeWall)/2,h=BarTubeLength); } translate([0,PinOC,-Protrusion]) rotate(180/TubeSides) cylinder(r=PinRadius,h=(PinTubeLength + 2*Protrusion),$fn=TubeSides); translate([-BarTubeLength/2,0,0]) rotate([0,90,0]) rotate(180/TubeSides) translate([0,0,-Protrusion]) cylinder(r=BarRadius,h=(BarTubeLength + 2*Protrusion)); translate([0,0,-(BarRadius + TubeWall + Protrusion)/2]) cube([(BarTubeLength + 2*Protrusion), BarTubeLength, (BarRadius + TubeWall + Protrusion)],center=true); } } //------- // Build it! ShowPegGrid(); Protector();And a bare-bones version:
// Dishwasher rack protector // Trivial version for OpenSCAD course // Ed Nisley KE4ZNU - July 2013 difference() { union() { translate([0,3.4,0]) color("lightgreen") cylinder(r=5,h=15); translate([-15.0,0,0]) rotate([0,90,0]) color("lightyellow") cylinder(r=6.0,h=30.0); } translate([0,3.4,-15.0]) cylinder(r=3.0,h=3*15.0); translate([-30.0,0,0]) rotate([0,90,0]) cylinder(r=3.0,h=2*30.0); translate([0,0,-5.0]) cube([50,50,10.0],center=true); }A simplified version of the Sink Drain Strainer I wrote up for Digital Machinist:

3D Printed Sink Strainer – overview // Strainer Plate // Simplified version for OpenSCAD course // Ed Nisley KE4ZNU - July 2013 Layout = "Build"; // Handle Plate Show Build Protrusion = 0.1; // make holes end cleanly PlateOD = 150.0; // strainer plate diameter PlateThick = 5.0; // .. thickness HoleOD = 6.0; // hole diameter NumRings = 4; // number of hole rings RingMinDia = 20.0; // innermost ring diameter RingStep = 30.0; // ring diameter increment HandleOD = 8.0; // handle diameter HandleLength = 15.0; // .. length HandlePegOD = HandleOD/2; // .. mounting peg HandlePegLength = 1.5; //-- Create single handle module Handle() { cylinder(r=HandleOD/2,h=HandleLength); cylinder(r=HandlePegOD/2,h=(HandleLength + HandlePegLength)); }//-- Create single ring of holes module RingHoles(RingDia,HoleDia,Thickness) { Num = floor(90/asin(HoleDia/RingDia)); // how many holes fit in ring? echo(str("Dia: ",RingDia," Holes: ",Num)); for(n=[0:(Num-1)]) { rotate([0,0,n*360/Num]) translate([RingDia/2,0,-Protrusion]) cylinder(r=HoleDia/2, h=(Thickness + 2*Protrusion)); } } //-- Create strainer plate with holes module StrainerPlate() { difference() { cylinder(r=PlateOD/2,h=PlateThick); for (RingID = [0:NumRings-1]) { RingHoles((RingMinDia + RingID*RingStep), HoleOD,PlateThick); } cylinder(r=HandlePegOD/2,h=3*PlateThick,center=true); } } //-- Build it! if (Layout == "Plate") StrainerPlate(); if (Layout == "Handle") Handle(); if (Layout == "Build") { StrainerPlate(); translate([PlateOD/2,PlateOD/2,0]) Handle(); translate([(PlateOD/2 - 2*HandleOD), PlateOD/2,0]) Handle(); } if (Layout == "Show") { color("LightYellow") StrainerPlate(); color("LightGreen") { translate([0,0,-HandleLength]) Handle(); translate([0,0,(PlateThick + HandleLength)]) rotate([180,0,0]) Handle(); } }And a bare-bones version, minus the handles:
Protrusion = 0.1; PlateOD = 150.0; PlateThick = 5.0; HoleOD = 6.0; NumRings = 4; RingMinDia = 20.0; RingStep = 30.0; module RingHoles(RingDia,HoleDia,Thickness) { Num = floor(90/asin(HoleDia/RingDia)); echo("Dia: ",RingDia," holes: ",Num); for(n=[0:(Num-1)]) { rotate([0,0,n*360/Num]) translate([RingDia/2,0,-Protrusion]) cylinder(r=HoleDia/2, h=(Thickness + 2*Protrusion)); } } difference() { cylinder(r=PlateOD/2,h=PlateThick); for (RingID = [0:NumRings-1]) { RingHoles((RingMinDia + RingID*RingStep), HoleOD,PlateThick); } }[Update: The talk went well and took a bit under three hours, although by mutual agreement we didn’t fire up the M2 at the end. I’ll work on a short talk about Design for Printability and we’ll run that with a separate printing session. A good time was had by all!]