Monday, 9 June 2014

Why slicers get the dimensions wrong

People using Slic3r often complain that holes come out too small, see forums.reprap.org. This blog post is in reply to the question here.

The issue is not just with round holes (which shrink for reasons I described here) but rectangular or hexagonal holes as well. I got my rectilinear dimensions correct with Skeinforge nearly three years ago and blogged the maths here. I now design exclusively in OpenScad using polyholes to get cylindrical holes the correct size as well.

I have tried Slic3r, Cura and Kisslicer but none of them print the Mendel90 calibration part the right size, so I have stuck with Skeinforge. It is looking a bit old now as Enrique seemed to stop developing it around the time people started saying "Slic3r is nicer", but at least it is stable and has very few bugs.

Looking at the G code produced by Slic3r and Cura, they both assume the extruded outlines have a rectangular cross section. I.e. if I work out the volume of plastic extruded from the E number and feedstock diameter and divide it by the length of the line then I get an area. This is equal to the layer height times the intended filament width and the outline is offset by half the intended filament width. The problem is the filament does not form a rectangle if the edges are not constrained. It forms a rectangle with semi circular ends due to surface tension. The actual width of an outline of a given area is therefore slightly more than it would be if it was a rectangle.
The cross sectional area of a filament with height h and width W is that of a circle with diameter h plus a rectangle of width (W - h) and height h. A = πh2/4 + h(W - h).

Solving for W gives W = A / h + h(1 - π/4).

But slicers output enough filament to fill the rectangle, so A = intended w × h. Substituting that value for A we get W = w + h(1 - π/4). So we have an additional width that is just a fixed multiple of the layer height.
I print a lot of things with 0.4mm layers, so the error is very significant. To fix it in Skeinforge I set the outline flow rate to be enough to fill the rounded rectangle, rather than the full rectangle. I achieve this by setting the "Perimeter Flow Rate Multiplier (ratio)" on the Speed tab. A value equal to the "Perimeter Feed Rate Multipler (ratio)" gives an area equal to the full rectangle. To correct for the fact that it is actually a rounded rectangle one has to multiply the feed rate by the ratio of the areas, which is 1 + (π/4 -1) h / w, a value which only depends on the w / h ratio.
As you can see, when the w / h ratio is high the reduction in flow rate necessary is only about 4%. I assume the reason a lot of people don't notice this is that they use a high w / h ratio and then calibrate a thin wall box, so that the flow rate is low enough to compensate without making the infill too sparse. I generally print with lower values of w / h and prefer to just put in numbers, rather than measure thin wall thickness.

An alternative way to compensate would be to keep the flow rate the same but offset the outline by W/2 instead of w/2. I.e. by an additional h(1 - π/4)/2.

If objects are printed with multiple outlines then the error appears much worse if the inner outlines are printed first working outwards (or the opposite for holes). Looking at the area of plastic this is not obvious mathematically because an additional area of plastic equal to w × h will extend the width by w, preserving the original error but not adding to it.

However, if you consider the practicalities of the process it is obvious that you can't squeeze viscous plastic into the infinitely sharp point under the overhang of the previous outline, particularly when the opposite edge is completely unconstrained. In practice I think you get something like this: -
The plastic that fails to fill the overhang causes the opposite edge to bulge a bit further and this effect then gives the cumulative error that I experience. I don't think the correction factor is easily calculated because it depends on the viscosity of the plastic as well as layer height, etc.

So if you want accurate dimensions and multiple outlines then do the outer perimeter first. For better seam hiding on objects where the dimensions don't matter do the inner perimeters first. I tend to print most things with one outline as you effectively get an extra one free with Skeinforge because it joins the ends of the infill, see hydraraptor.blogspot.co.uk/2008/04/python-beans-make-object.

16 comments:

  1. Just a note: Slic3r does NOT assume that extruded lines have a rectangular cross-section.
    The thread you linked contains this diagrams that shows the used shape: http://forums.reprap.org/read.php?263,273929,289730#msg-289730

    ReplyDelete
    Replies
    1. That isn't what I found when examining the G-code but it was many months ago. However that diagram shows it has different formulas depending on the width compared to the nozzle diameter. That is simply wrong. It should always be a flattened bead.

      Delete
  2. Most situations will fall in the case that has semicircular ends, but you can't assume shape will be the same for *any* amount of material. That is wrong. Any hypothetic shape has a range (min/max) where it's applicable.
    Suppose you extrude 10x the normal amount, you won't definitely get a rectangle with semicircular ends. You'll get some other shape since material will curl on the sides. Similarly, if you extrude a very low amount of material (less than what's needed for filling all of the volume below the nozzle), you'll get some other shape. This is why I use a *single* function made of continuous formulas.

    ReplyDelete
    Replies
    1. Both those cases are failures for 3D printing. For all functional extruding of outlines this model applies.

      You can't build things when the extrusion rate is so high it exceeds the nozzle tip width because it would leave raised ridges that the nozzle would plough into.The lower limit is when w =h and it becomes a circle. Gravity means it is actually slightly flat on the bottom and has some adhesion rather than a perfect circle with zero adhesion.

      Delete
    2. I'll try and shove this math into MatterSlice in the near future. I have the philosophy that whatever a nop head wants a nop head gets.

      Delete
  3. Viscosity is a factor, but it enters into play at both the upper and lower flattened surfaces. However, viscosity is a function of temperature as well as of the material used, etc. The bottom layer and the plastics making contact sideways, are cooler than the extrudate and also have much higher thermal conductivity than the air, which means that they thermally influence the part they make contact with, more. That might explain why the top (hot) and bottom (cold) sections are shown not shaped similarly, e.g. the upper section filled while the bottom is not.

    Assuming a correction factor is somehow calculated or empirically found, I'd guess that the surfaces (here, the curves) are tangential among them. So, it could be graphically represented, in a deterministic way. No?

    ReplyDelete
  4. Hello Chris,
    your article is not entirely correct. Slic3r has been using the rectangle model only for a very limited set of cases. In most situations, Slic3r already uses the same model that you're describing here (rectangle with semicircles). So I think you should correct the wrong statement in the article.

    After some public discussion in the Slic3r forum (http://forums.reprap.org/read.php?263,273929,page=6), I decided to apply such model also to those limited cases where the rectangle was used. This is going to be included in the upcoming 1.2.0 release.

    However, some quick math shows clearly that this change is going to affect dimensions very very little. Using a spreadsheet I calculated how thinner would extrusion width be in those limited cases where a rectangular section was assumed, i.e. how much would the error be reduced by.
    To do this, I calculated the cross-sectional area with current formula, and then divided using the new formula solving by width.
    For a 0.35mm nozzle and 0.1mm layer height, the actual width (according to the new formula) will be -0.02mm over the current one. And -0.06mm for a 0.4mm layer height.

    0.02-0.06mm is way smaller (an order of magnitude!) than the usual dimensional issues people are noticing. Other factors (for example: backlash) do have a larger impact on dimensional errors. So I think your article is not entirely correct in saying that holes are smaller because of the flow math adopted by software. That's just one of many factors, and not the main one.

    I recommend users to read this page for a wider view: http://manual.slic3r.org/troubleshooting/dimension-errors

    ReplyDelete
    Replies
    1. You say it is limited cases but I nearly always print in the range where the flat section is smaller than the nozzle. With a 0.45mm nozzle and 0.4mm layers it would need a width of 0.85mm and that is not possible because the area would be bigger than the die swell.

      Even with 0.2mm layers and a 0.4mm nozzle you would need to have a width bigger than 0.6mm to get the correct maths. I.e W/H bigger than 3!

      I have done tests between Skeinforge and Slic3r using the same firmware and machine and got different dimensions, so backlash and calibration, etc., are out of the loop.

      Delete
    2. Being open source software, you can verify my words by checking the C++ code and the documentation. :-)
      And I still ask you to rectify the wrong statement about Slic3r's flow model. It's a matter of fact...

      Discussing how 'limited' is the case is a bit pointless: even in those cases, the hypothetical width error is about 0.02-0.06mm. Not very significant.

      Also, this article starts with "This blog post is in reply to the question here". Using the settings from the linked forum post, the difference by adopting the other flow model would be -0.05mm, which is way less than the errors he measured. So I think this blog post does not really answer the linked question because it focuses on a very minor potential cause.
      (By the way, -0.05mm is even less than the difference in error he measured between X and Y, 0.1mm, that he thinks might be caused by mechanical issues in the Y axis.)

      Anyway, as I said, release 1.2.0 will include that flow model change even for those cases so we're discussing about the past. Still, the forum post will be left unanswered...

      Delete
    3. Blog articles are anchored in time, that is where the log bit in the name comes from. If you fix slic3r afterwards it doesn't mean the article should be removed. I might do a follow up when 1.2.0 is released and see if it matches Skeinforge for accuracy. In theory the parts from the same STL and the same machine should always have the same dimensions. My experience with Skeinforge , Slice3r, Cura and Kisslicer is only Skeinforge prints the same size as the STL.

      Also the article doesn't attribute all the error to the flow rate. The bigger problem is when printing multiple outlines with the inner ones first for the reason mentioned at the end.



      Delete
  5. At the time you wrote the article, Slic3r had already been using the rectangle model with semicircles for most cases for at least a couple years. Probably more. This can be verified in Github...

    ReplyDelete
    Replies
    1. You say "most cases" but how many people print with the flat part of the filament wider than the nozzle aperture? I.e. W > nozzle + H.

      I never print like that because when I print very thin layers I keep the width close to the nozzle size for good resolution. When I print thick layers for high productivity the width is limited by the die swell, so I am always in the case where W < nozzle + H and the rectangular section is less than the nozzle.

      Delete
  6. Great info!
    Does skeinforge have a setting to offset the outline while keeping the flowrate teh same as you mention in your alternative approach?

    ReplyDelete
  7. The offset is always half the width on the carve tab and you can set the outline flow rate on the speed tab, so the answer is yes but you need to do the maths yourself.

    ReplyDelete
  8. Do you mean changing the perimeter feed rate in the speed tab?
    I can see how increasing just the feed rate would inset the perimeter while keeping the flow rate the same.
    Are extra shells in fill calculated with the perimeter or the infill value though?

    ReplyDelete
  9. The flow rate to feed rate ratio determines the area of the filament cross section. A ratio of 1 corresponds to a rectangular area of width x height. So yes you can get the correct flow rate for the semicircular edges by increasing the feed rate.

    I don't use extra shells, so not sure what rate is used.

    ReplyDelete