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

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

, ,

14 Comments