cadquery icon indicating copy to clipboard operation
cadquery copied to clipboard

STL export of object with twistExtrude through-hole produces spatially-varying geometric inaccuracy

Open r-terrett opened this issue 3 years ago • 4 comments

The problem:

Hi,

I am attempting to produce a cylinder with one or more helical through-holes. Please consult the following MWE:

import cadquery as cq
from cadquery import exporters

G_RADIUS = 0.25
G_LENGTH = 1.0
T = 6
P_RADIUS = 0.1  # Fraction of radius
P_OFFSET = 0.5  # Fraction of radius

FILLET_RADIUS = 0.01
CENTER_PUNCH = True

abs_p_radius = P_RADIUS*G_RADIUS
abs_p_offset = P_OFFSET*G_RADIUS

cyl = cq.Workplane("XY").circle(G_RADIUS).extrude(G_LENGTH)
cut1 = cq.Workplane("XY").center(abs_p_offset,0).circle(abs_p_radius).center(-abs_p_offset,0).twistExtrude(1,180)
cut2 = cq.Workplane("XY").circle(abs_p_radius).extrude(1)
cyl = cyl.cut(cut1)
for i in range(0, T):
    cyl = cyl.cut(cut1.rotate(axisStartPoint=(0,0,-1), axisEndPoint=(0,0,1), angleDegrees=360/T*i))
if CENTER_PUNCH:
    cyl = cyl.cut(cut2)

result = cyl
result = cyl.clean().fillet(FILLET_RADIUS)
exporters.export(result, '/tmp/test.stl')

This code defines a cylinder, a series of radially offset twistExtruded cylinders and a non-twisted central cylinder, the latter two of which are subtracted from the first.

This geometry looks good in CQ-editor:

cyl-1

However inspection of the derived STL file shows that the cross section of the helical through-holes deviates from circular towards the center of the cylinder, with the holes eventually vanishing:

cyl-2

n.b. These cross sections are from PrusaSlicer. the wavy red stuff is a non-solid gyroidal infill for 3D printing and not part of the STL geometry proper, hopefully you get the idea.

Things I've tested:

  • Linear through-holes do not exhibit this.
  • Increasing the hole diameter, decreasing the helical pitch, or shortening the cylinder ameliorate the problem. Under some circumstances I get holes that go all the way through but again exhibit spatially-varying deviations from circularity in the hole cross-section. Geometries with a sufficiently large hole radius or low pitch do not exhibit the problem. I therefore suspect this has something to do with the total angle of the twistExtrude, rather than the pitch directly.
  • Removing the fillet does not help.
  • Decreasing the STL export tolerance does not help.

Questions:

I would like to be able to parametrically generate geometries like this, but with consistent helical holes of circular cross section (within reason of course). If this is known or expected behaviour, what is its root cause and how do I fix/predict/avoid it?

Thanks for any help anyone can provide.

Version: cadquery 2.1

r-terrett avatar Jan 26 '22 05:01 r-terrett

I first checked with sections to see if the holes are correct in CQ-editor, and they stay consistent at 0.2, 0.25, 0.5, 0.75 heights.

section = result.section(height=0.5)
show_object(section)

Screenshot from 2022-01-26 07-33-43

I then tried exporting with different tolerances using the following code, without any luck at fixing the issue.

result.val().exportStl('/tmp/test.stl', tolerance=0.0005, angularTolerance=0.05)

Be careful if you try this code though, some tolerance settings will lead to extremely long export times. When imported in Prusa Slicer the STL had between 48 and 96 errors that had to be repaired, depending on the tolerance settings, so something is not working correctly with the export.

I also tried exporting to STEP and then exported that to STL from FreeCAD. The STL still had the same problems. You can see artifacts in the STEP import that would be consistent with the problems in the STL with the transparency set to 50% on the object in FreeCAD.

Screenshot from 2022-01-26 07-28-46

The only way I was able to get a good result was by switching the circle profile for the twistExtrudes to rectangles.

cut1 = cq.Workplane("XY").center(abs_p_offset,0).rect(abs_p_radius * 2, abs_p_radius * 2).center(-abs_p_offset,0).twistExtrude(1,180)

jmwright avatar Jan 26 '22 12:01 jmwright

Looks like some tessellation bug of OCCT. Take a look here for a possible workaround: https://github.com/CadQuery/cadquery/issues/367 .

adam-urbanczyk avatar Jan 26 '22 17:01 adam-urbanczyk

Hi,

I did some experimentation with netgen.occ as per #367 . This obtains through-holes that go all the way through and retain approximately circular cross section: cyl-3 cyl-4

The mesh here has some slight irregularities which I suppose are due to the tessellation algorithm (hmax=0.01, optsteps2d=4), however these are hopefully not significant for my purposes.

Unfortunately cq-editor does not carry netgen along with it so I had to construct a miniconda environment but within that context it seems to work. More generally, is it (in principle) possible to configure a cq/netgen stack as a collection of site packages? I'd like to run cq programmatically using a batch system I don't control and it's unlikely that I'll have the flexibility to create and activate conda environments in that context. If not, no big deal.

Otherwise, my problem is solved, thanks for your help.

r-terrett avatar Jan 27 '22 04:01 r-terrett

Not related to the issue itself, but you could try using tools like https://conda.github.io/conda-pack/ or https://github.com/conda/constructor .

adam-urbanczyk avatar Jan 31 '22 20:01 adam-urbanczyk

Fixed in OCCT/OCP 7.7.0.

OCP7.6.3 on left, OCP7.7.0 on right (PR #1215): image

lorenzncode avatar Jan 09 '23 03:01 lorenzncode