Monday, 20 July 2020

Horiholes 2

As whosawhatsis pointed out in a comment on my last post, the edges of the filament staircase are actually semicircular and that makes a big difference as to where they should be to meet the circle tangentially. Not sure why I missed that as I have done several posts about extruded filament shape, I must be losing it!

This is what my previous shape actually produces.

The circle only touches at four points. The correct shape is obtained by calculating where the semicircles meet the circle.

The centres of the ends of the filament lie on a circle with a radius of the hole plus half the filament height. The end of the filament is then offset inwards horizontally by half the filament height. I.e. the slicer samples the layer at the central tip but the filament touches the circle on a tangent.

To make the shape geometrically I make a teardrop with a radius of the hole plus half the filament width, split it in half and shift the two halves together by half the filament width. As can be seen here that goes through all the filament tips, i.e., where the slicer samples.

This is what it looks like relative to the target hole.

Interestingly it is the same as my previous attempt at the top, bottom and sides, i.e. the only four points it touched before.

I made a test with the new formula.

The plug gauges all fit, but more snugly than before, so this is definitely a better solution for supporting a bearing in a pocket. At every layer it should have a tangential support from the rounded edge of an extrusion.

Here is a close up of the 6mm hole that is aligned on a layer boundary and the 1mm hole above it.

I have updated NopSCADlib on Github to use this method.

Saturday, 18 July 2020


Back in 2011 I came up with polyholes to get around the problem of 3D printed vertical holes coming out too small. Horizontally printed holes also come out too small but for a different reason: the slicer creates a staircase approximation of the hole, but because it samples the model at the middle of the layer, the top or bottom corners intrude into the circle.

 This shows a 6mm truncated teardrop sliced with 0.25mm layers, with red highlighting the overlap.

A long time ago I mitigated this by adding 1/4 of the layer height to the radius, for reasons I can't remember now, but it isn't very accurate. There is some slight interference vertically and gaps at the sides.

I am currently designing a gearbox with ball bearings in 3D printed pockets, which I want positioned accurately, so I decided to revisit the problem.

The correct solution is simple: the compensated shape for the teardrop is simply the hull of itself shifted up half a layer and shifted down half a layer. That compensates the top half so that the bottom of the layer ends up on the circle and the bottom half so that the top of the layer ends up on the circle.

So now all the tips of the stairs sit exactly on the circle, except near the top where the 45 degree overhang would be exceeded.

This is what the hole looks like before it is sliced.

It does of course make the model specific to being sliced at a certain layer height, but my models tend to be designed that way anyway,

I printed this test piece with 6mm holes at different offsets from the layer boundary as well as holes from 1mm to 5mm and I tested it with plug gauges.

The gauges fit all the holes easily. Some are snug and some have a little play vertically depending on how the top edge aligns with the layer boundaries.

The bridge layers over the top come out a bit low because the filament forms a cylinder from a volume that would normally almost fill a rectangle, making it a slight interference fit when the top  lines up exactly with the layers. In other cases there is a bit of vertical play due to the 45 degree limit at the top of the teardrop. This won't be an issue with my gearbox because it will be split into top and bottom halves and the top half will be printed upside down.

I have updated teardrop_plus() in NopSCADlib to use this method and also added a plus option to all the other variants like tearslot(). See and where you can find the code to make the test STL. 

It should work universally as long as all slicers slice in the centre of the layer. Obviously it makes less difference with smaller layer heights.

Thursday, 13 June 2019


When I used OpenSCAD to design Mendel90 I modelled complete assembly views with all the vitamins in place and a significant part of the code was actually the vitamins. Vitamins being the RepRap term for non-printed parts of a 3D printer, fasteners, motors, etc. I also automated the generation of the bill of materials, STL files, DXF files and PNG assembly views, but making the build manual was still a lot of manual work, pardon the pun.

After Mendel90 production ended I started designing other projects and found myself needing to use its vitamin library, but because it wasn't designed to be stand alone, that quickly got messy. Eventually I made a new stand alone library and a more general Python framework that would work for any project.

Over the last few years I have refactored it many times, making it much faster to preview, more general and more automated. In particular it can now catalogue all the vitamins and automatically make build manuals for any project using Markdown embedded in OpenSCAD comments. There is a simple example here. I also added reusable printed parts, such as feet, hinges and handles and some reusable enclosures.

It will never be complete because each significant project I make with it usually needs a few more types of vitamin, but it is hopefully structured so that it can grow sustainably without bringing OpenSCAD to its knees. To do that I had to fix some issues in OpenSCAD itself because it used to slow down exponentially with the number of files used. The picture above has an instance of every part in the library. The latest release of OpenSCAD can draw it in about one minute on my desktop PC. This is remarkable because at one time it took 12 minutes.

Here is an example of a typical assembly views it creates: -

I have published it open source on GitHub to enable me to publish projects that use it in the future. I use it for every project I make now, so I don't have any stand alone scad files that can be put on Thingiverse, for example. Feel free to use it in your own projects.