Thing-O-Matic: Small Features

Strainer - knob perimeter thread
Strainer - knob perimeter thread

It seems most of the stuff I build with my Thing-O-Matic involves small features and thin sections that bump hard against the minimum possible sizes. I’ve found that forcing critical solid model dimensions to be integer multiples of the the extrusion width or thickness stabilizes the whole idea→model→G-Code→object chain by encouraging Skeinforge to make the choices I prefer.

Or perhaps I’m just constraining my choices to make Skeinforge happiest. One can view reality in many ways…

Anyhow, my OpenSCAD programs tend to have these lines up near the top:

ThreadThick = 0.33;
ThreadWidth = 2.0 * ThreadThick;

function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);

The ThreadThick parameter matches the Skeinforge thread thickness parameter(s) and the 2.0 matches the w/t setting(s). Those correspond quite closely to the actual printed results, as tediously verified through many measurements. Throughout the rest of the OpenSCAD program, I compute the dimensions of key features using those sizes as building blocks.

The IntegerMultiple function returns the next higher multiple of the basic Unit that’s greater-than-or-equal-to the desired Size. Feeding in the thread thickness or width as the Unit ensures that the result will be an integer multiple of the smallest-possible dimension and won’t be smaller. The integer limit happens automagically, because the printer can’t lay down anything else, but a less-than-possible size can cause features to (unpredictably, in my experience) vanish without warning. This way your model reflects the printed reality and Skeinforge seems more likely to produce a predictable result.

So the parameter controlling the thickness of a flat sheet might look like:

PlateThick = IntegerMultiple(2.0,ThreadThick);

Given ThreadThick = 0.33, the sheet will be 7 layers thick = 2.31 mm. If the sheet must not exceed 2.0 mm, however, then you need a similar function with floor(), which may eradicate very small features.

This trick seems most useful for thin wall sections, because the wall width directly affects the fill:

  • Less  than 1 thread width can’t be built
  • Exactly 1 thread width is the thinnest possible wall
  • Widths between 1 and 2 thread widths may be either, depending on surrounding features
  • Exactly 2 thread widths produces a nice wall
  • Widths between 2 and 3 thread widths can’t fill properly
  • Exactly 3 thread widths fills perfectly
  • Over 3 thread widths generally fill properly

So making the rim around a recessed lid become an integral number of thread widths, with a minimum width of 1.0 mm, looks like this:

LidMargin = IntegerMultiple(1.0,ThreadWidth);

With a 0.66 mm thread width, the nominal wall is 1.5 threads wide and could print as either 1 or 2 threads, depending on other factors. Rather than leave the results to chance, I force the solid model wall to be exactly 2 threads wide to make the printed result come out at 1.32 mm. Because I don’t care exactly how wide the lid margin is, as long as it’s at least one thread, that’s fine with me.

Generally, the values come from computations based on other dimensions, so quantizing the results keeps the printed result stable over small variations of those inputs.

If I ever get around to changing the nozzle to from 0.5 mm to 0.4 mm, I’ll probably change the thread dimensions to 0.25 mm x 0.5 mm (keeping the same 2.0 w/t ratio). A 1.0 mm wall would then still be exactly 2 threads wide and come out looking exactly the same, but with a total width of 1.00 mm.

That’s the intent, anyway.