10
$\begingroup$

Z-fighting is a 3D rendering artifact of coplanar surfaces (means, of triangles located in exactly the same plane and overlapping each other).

It can happen in OpenSCAD's preview mode when doing a difference() or union() operation. In case of difference(), the rendering artifacts can prevent seeing into a hole in the object. The "compile and render" mode in OpenSCAD does not have z-fighting issues. But since it can take some time to render an object in that mode, it is not a practical solution during development.

How best to avoid z-fighting?

If the answer involves changes to my OpenSCAD code, I would love to see an idiomatic answer / established convention of OpenSCAD coders, if that exists.

$\endgroup$

1 Answer 1

11
$\begingroup$

The general advice in the OpenSCAD community is to "extend your cuts and embed your joins" (source). The rendering artifacts are one thing but rather just an annoyance; however z-fighting can also cause unexpected errors during STL export (I did not experience that myself so far, just read this somewhere).

So you would change the dimensions of your objects very slightly (0.01 mm works fine) so that:

  • for a union(), there is overlap volume between the parts
  • for a difference(), the intersector has volume both inside and outside of the intersected part

Now you could adjust both the size and position of your parts to keep the mathematically exact dimensions for the resulting part. But I found that for the purposes of 3D printing, such accuracy is not worth it because it complicates the formulas so much.

Instead, I adjust either position or size of a part, depending on what is simpler in each case. A measure in the final design will be off by 0.01 mm, which does not matter.

And I keep the 0.01 mm offset in a variable called nothing (picked that up somewhere and liked it …). This keeps the calculations intuitively understandable.

Example

To create a cylinder and cut a hole to half of its depth, I would do this:

//!OpenSCAD
nothing=0.01;
height=40;

difference(){
    cylinder(h=height, r=20, center=true);

    translate([0, 0, height/4 + nothing]) 
        cylinder(h=height/2, r=15, center=true);
}

Now the hole is nothing=0.01 less deep than half of the cylinder – that's the inaccuracy I accept.

(Note: If you don't have OpenSCAD installed, you can also try the above code online by copy & pasting it into OpenJSCAD. Include the magic comment in the first line to switch it to OpenSCAD syntax.)

$\endgroup$
5
  • 1
    $\begingroup$ Your answer is the one I'd post for this question. You add the parameter "nothing" while I use "addabit = 0.1" for most z actions. $\endgroup$
    – fred_dot_u
    Apr 26, 2019 at 20:18
  • 1
    $\begingroup$ This may improve the STL generation. OpenSCAD has two rendering systems. The first is used for quick display of the code. The second is much slower and must be run before generating STL. In my experience, the first is prone to this problem with zero-thickness layers, but the second is more accurate and is not prone to this problem. Your experience may be different, but I have not generated bad STL files for images with this display artifact. $\endgroup$
    – cmm
    Jun 25, 2019 at 14:21
  • $\begingroup$ @cmm Same here, I also only saw z-fighting in the preview rendering mode so far. The STL issue is something I picked up somewhere else. I made this distinction explicit in the answer now. $\endgroup$
    – tanius
    Jun 25, 2019 at 15:23
  • $\begingroup$ You could increase the height of the object by nothing to have a perfect part. $\endgroup$ Jun 28, 2019 at 10:40
  • 1
    $\begingroup$ I also saw this variable being called tolerance, which I personally find less amusing but more descriptive. $\endgroup$
    – user31389
    Sep 27, 2021 at 22:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .