# Archive for September 26th, 2013

### 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

Protrusion = 0.1;							// make holes end cleanly

//-------
// Dimensions

PinDia = 4.0 + 0.5;                 // upright pin diameter + clearance

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

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)

translate([-BarTubeLength/2,0,0])
rotate([0,90,0])
rotate(180/TubeSides)
translate([0,0,-Protrusion])

cube([(BarTubeLength + 2*Protrusion),
BarTubeLength,
}

}

//-------
// 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!]