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