CAD Software Achieving accurate printed dimensions using OpenSCAD


Lorenzo von Matterhorn
Jan 31, 2009
Reaction score
Very important for this hobby since we are typically limited by standard body tube dimensions.

Finding Perfect Part Fits the Goldilocks Approach and OpenSCAD


There is something to be said for brute force or trial-and-error approaches to problems, especially when finding a solution has an empirical element to it. [Tommy] perceived that to be the case when needing to design and 3D print servo horns that would fit factory servos as closely as possible, and used OpenSCAD to print a “Goldilocks array” from which it was possible to find a perfect match for his printer by making the trial and error process much more efficient. By printing one part, [Tommy] could test-fit dozens of options.

What made doing this necessary is the fact that every 3D printer has some variance in how accurately they will reproduce small features and dimensions. A 6.3 mm diameter hole in a CAD model, for example, will not come out as exactly 6.3 mm in a 3D-printed object. It will be off by some amount, but usually consistently so. Therefore, one way around this is to empirically determine which measurements result in a perfect fit, and use those for production on that specific 3D printer.


Some of the comments:

Pixel_K says:
June 9, 2020 at 9:18 am

One very important detail missing in the article, is that OpenSCAD “holes” (cylinder) will never be the size you specify if you don’t understand how they’re made : they are an approximation of a circle, a polygon fitting within the specified diameter. As such the printed hole will always be smaller than the diameter you specified. The OpenSCAD team is well aware of of this and it’s well explained in their faq, and there also a formula there to compute the diameter to pass to the software to get the desired result. A gotcha for newcomers for sure.


Doug says:
June 9, 2020 at 9:42 am

I’ve found both issues (approximate circles and printer accuracy) and the definitely compound each other. I’ve definitely done my share of “grid of ever increasing hole sizes” a few times.

I usually leave the $fn at the top of the file fairly low (like 30) while designing (to speed up render times), then crank it up to 200-500 depending on part sizes and tolenrences for cura. This helps with the “approximate” problem since a small circle made of 200 polygons is going to be pretty darned round. You also have to consider that the stepper motors are also linear x/y drives, so you’ll never get a *perfect* curve out of an FDM 3d printer anyway (resin printers have a finite resolution, but it’s high enough you’ll probably never notice). The larger the holes, the higher your $fn should be since it’s usually the absolute accuracy (not relative accuracy) that’s important.

The main reason 3d printers print holes the wrong size is because the plastic is not super viscous when it comes out, so it tends to “drag” around the inner diameter a bit, closing the hole slightly. As the hole size increases, the angle (relative to the circle’s tangent) the printer is “dragging” the molten plastic by the time it hardens decreases very quickly, so the effect is mostly seen in small holes (less than 10mm in my experience). This makes it tricky to predict how much hole shrinkage you’ll get since the variance depends on your filament material, temperature, feed rate and hole diameter, hole orientation and probably your nozzle diameter as well (I’ve only done .4mm so far). Also, don’t forget that while horizontal holes don’t have the drag problem (since they’re effectively rectangles stacked in the slicer), but the tops tend to sag more as your hole size increases.

So the drag problem mostly affects smaller holes, while larger holes sag and are more affected by the $fn value, but medium holes can sometimes suffer from multiple factors if you’re not careful. So if I have a print that’s going to take a while and has holes that need to be accurate, I’ll usually do a quick test print with the hole sizes (in their final orientations) as a double-check before committing hours (and filament) to the final print.


donotdespisethesnake says:
June 9, 2020 at 9:48 am

I used a different approach. set $fn=0, $fa=0.01 then use $fs to set the resolution. You can use $fs=1 or 2 for draft, and set to 0.2 to 0.5 for “quality”.

anszom says:
June 9, 2020 at 9:56 am

I’ve found $fn to be not generally useful. In my common OpenSCAD include file, I use $fa=1; $fs=0.5;

$fs=0.5 means that the circles will be split in segments no longer than 0.5mm. This ensures that circles large and small will have consistent precision.

$fa=1 means that the circles will be split in at least 1-degree arcs. Otherwise the default of 12 will be used and you will get no more than 30 segments in a full circle


Elliot Williams says:
June 9, 2020 at 1:43 pm

If you’re doing polygons instead of circles, you inevitably have to choose the inside diameter or the outside diameter. (Inscribed or circumscribed circles.) One is good for holes, the other is good for pegs, neither one is “right”. OpenSCAD sizes “circles” using the outside diameter.

If you want to scale up your holes, you can increase the outside radius/diameter by a factor of how many sides it has.

function corrected_radius(r, n = 0) = r / cos(180 / n);

Nophead did this with his “polyholes” waaay back in the day:

There’s other factors, like drag on the plastic and extrusion multipliers and backlash and simple tolerance in the part that will make you still want to add some part/machine specific slop, so this procedure is a good one.

When I need an important fit, I always plan to drill it out or print a couple of the critical bits until it works. This disciplined approach sounds good to me!