This post describes the behavior of an older version of Cura. The explanation of how the nozzle and wall thicknesses work together is still relevant, and useful to know, so I’ll leave the post here. The limits on extrusion rate are also still an important factor to bear in mind when setting up a print. However, the specific bug that I document regarding the positioning of extrusion lines has been fixed since Cura 13.04 (and versions from 13.05 onwards use a totally different slicing engine).
Lately I’ve been looking at the nuts and bolts of gcode quite a lot, as I’ve been helping people troubleshoot prints, and get new printers working. One of the things I’ve done is set up a spreadsheet that reads a gcode file, and works out the distance that the head is moving, and the amount of plastic being extruded, and then compares that to what we would expect, based on the layer height, and extrusion width.
This was what led me to realize that Cura does something slightly odd, if the wall width isn’t an exact multiple of the nozzle size. And in fact,I realized today that what it does isn’t just odd, but in fact, wrong. (And to be clear, I’m talking about the current behavior, as of Cura 13.03, which still uses Skeinforge as the underlying slicer).
Normally, for a standard Ultimaker printer, you would set the nozzle size to 0.4mm – the size of the physical hole in the nozzle. And then you also set a wall thickness that is a multiple of that. For instance, with a 0.8mm wall thickness, you get two loops around the perimeter of the object you are printing on each layer. Each loop lays down a bead 0.4mm wide, the natural width of the bead of plastic that squirts out of the nozzle, for a combined width of 0.8mm.
The edge case
What is not well documented, or generally understood, is what happens if you specify a wall width that isn’t an exact multiple of the nozzle size (although the tooltips on the fields in Cura do give some information if you try to put in wildly incorrect values). What happens is that Cura changes things behind the scenes. For the most part, what happens is that Cura changes the effective nozzle size setting, such that the wall size remains and exact multiple of the nozzle size, provided that the nozzle size doesn’t increase by more than 50% of its stated ‘true’ width. If it would go over 50% of its size, then instead Cura acts as if the nozzle is smaller than its true width, and plans on making multiple loops to make the walls.
For instance, assume that the nozzle is given as 0.4mm wide. These are some of the combinations that Cura will give you:
- If you ask for a wall of 0.4mm, that is what you get – a single loop, 0.4mm wide;
- If you ask for a wall of 0.8mm, then you get two loops, each 0.4mm wide;
- If you ask for a wall of 0.6mm, then Cura assumes a nozzle width of 0.6mm, and gives you a single loop, 0.6mm wide as the perimeter of your object;
- If you ask for a wall of 0.7mm, then Cura decides that’s too wide to do with a single loop for a 0.4mm nozzle. Instead, it acts as if your nozzle is 0.35 mm wide, and gives you two loops of that thickness to make up the 0.7mm.
So far, so good…
All of which would be well and good, and even helpful, if Cura got it right when changing the nozzle size on the fly, but it doesn’t. It does act as if the nozzle is the newly calculated size when calculating extrusion amounts. Skirt, loops, perimeter and infill are all extruded at new rates, as if the nozzle really was the new size. For instance, in the case of a 0.6mm wall, above, everything gets extruded at 1.5 times the normal 0.4mm nozzle rate, to lay down a bead 0.6mm wide everywhere.
And the outermost perimeter is positioned correctly, based on the deposited bead of plastic being 0.6mm wide, so the other dimensions of the object are correct (at least before any shrinking due to cooling). This is definitely a good thing.
But there’s a catch
The problem is that everything else is positioned relative to that, but based on the assumption that the nozzle is still the original 0.4mm size. This means that, for instance, in the case of 0.6mm walls solid infill in the bottom of the print extrudes enough for 0.6mm wide lines, but positions them every 0.4mm – resulting in 50% over-extrusion.
Conversely, in the 0.7mm wall example, the outer perimeter is positioned correctly, but the inner loop is printed 0.4mm inside it, not 0.35mm, and then the infill is spaced 0.4mm apart, even though there’s only enough plastic being extruded to make lines 0.35mm wide.
Demonstrating the problem
In order to test out what is going on, I took a small cup object, and sliced it with a 0.4mm nozzle, and various wall thicknesses – 0.25mm, 0.4mm, 0.6mm, 0.62mm, and 0.7mm. Then I loaded the gcode up into Repetier Host to visualize it, and into my analysis spreadsheet to check the extrusion amounts. And what I saw was as described above.
For instance, this is the base of the cup sliced at 0.6mm wall thickness, as viewed in Repetier Host:
Notice that the outer skirt and the perimeter are laid down quite thickly, but the inside infill looks thinner – it is spaced correctly at 0.4mm, which would be fine except that what Repetier Host isn’t showing is that it is actually laying down enough plastic for 0.6mm wide lines. This can be seen in the analysis spreadsheet that looks at snippets of gcode from each section of this layer:
This spreadsheet looks at the X, Y and E coordinates from three series of G1 move commands within the gcode for the same layer shown above. For each, it calculates the distance moved in X and Y axes, and the amount of plastic extruded, given the amount of E movement, and the stated filament diameter. Then it compares this to the expected extrusion volume, for a bead of plastic of the given width and distance, and the specified layer height.
As you can see from the last column, all the moves extrude the right amount of plastic for a 0.6mm wide bead, and 0.2mm layer height. (The slight variations in percentage are due to rounding errors, given the tiny actual and predicted volumes involved in these short segments.) So we are printing enough plastic as if we had a 0.6mm wide hole in our nozzle, and are laying down a bead that wide.
However, as the red notes on the infill section show – the little connecting lines at the ends of the long infill segments are only 0.4mm long still: the infill lines are 0.4mm apart; that is, spaced correctly for the original nozzle width.
Conversely, for a 0.25mm wall, here is what the gcode looks like:
Notice that the perimeter and infill lines are thinner – but the infill is spaced the same distance apart as in the first picture above. The spacing is still 0.4mm, and so there are clear gaps between the lines of infill (this is easier to see at the the ends of the rows where the head turns round and heads back the other way). Running this through the spreadsheet confirms the findings – that the lines are the right width, but the short infill lines are still 0.4mm long, making the infill full of holes.
The same pattern repeated in each test case. I confirmed the diameter of the print by looking at the coordinates of the left- and right-most segments in the perimeter each time, and calculated the diameter, allowing for the width of the bead being printed. In each case, the printed diameter of the outside of the print was the same – 22.907mm – so Cura is correctly positioning the perimeters, based on the width of the extrusion. But in the case of the tests where Cura decided to reduce the nozzle size, and print two loops to make up the wall width, the inner loop was printed with slightly too small a diameter, as if spaced 0.4mm inside the perimeter, not the actual extrusion width:
(Note the positioning of the inner loop is subject to slight rounding errors, so the position is slightly off from its theoretical value, but in general, it is clear that the inner loop has been positioned as if it and the outer perimeter are both 0.4mm wide).
What to do about it
Mostly, this is just something to be aware of. Cura is currently undergoing big changes, and Daid should be rolling out the new ‘Steam Engine’ slicer underpinnings for Cura before too long. Hopefully that won’t suffer from these issues. In the meantime, I strongly recommend keeping your wall thickness setting an exact multiple of the nozzle width. However… there is one area where this might be more significant, insofar as it affects new users, doing their first ‘quick’ print.
Yeah? So what’s this got to do with QuickPrint mode?
Cura’s QuickPrint mode is the initial ‘simplified’ user interface that most new users start out with. With their freshly assembled Ultimaker, they fire up Cura, and it gives them a sample model, all ready to slice. And three option for quality: High Quality, Normal, and Fast.
And if you look under the hood at the settings that are used, the ‘Fast’ mode (and what new user doesn’t want to print something FAST!!??) falls into exactly the trap discussed above. In the interests of laying down as much plastic as possible as fast as possible, it sets the nozzle width to 0.4mm, and the wall width to 0.56mm.
And that means that as soon as the print starts, it’s going to print 0.56mm beads of plastic where there is only space for 0.4mm beads – that’s an over extrusion of 40% when filling in the solid parts of the object, and that probably not going to be the best possible experience for new users, nor the best possible print quality.
Furthermore, I believe the settings are also over aggressive in terms of speed and layer depth. Fast mode calls for 0.25mm layers at 80mm/s. That works out to 80 x 0.25 x 0.56 = 11.2mm³ of plastic per second. And that’s probably more throughput than a standard nozzle can handle (especially on a not very well optimized machine), and it is going to compound the problems, and cause slipping, grinding, head blockages, and again a fairly frustrating experience for new users. But that’s the subject of another blog post, coming soon…