Describe the bug
I had some trouble producing a torus also defined by
path_sweep(path=path3d(circle(d=9.5)), shape=circle(d=0.4), closed=true);
which should have been possible using
torus(d_maj=9.5, d_min=0.4);
But is not - nothing is rendered.
I thought I might have misunderstood the docs and used Claude Opus on the source to figure out if I missed something, and it claimed to have found a bug. I applied the fix and it seems to be at least correct for my case (the fix was previously applied to a function version elsewhere). I found a similar issue with the function version being correct, but the module not - probably a lack of test coverage, but I haven't dug that deep myself.
Let me quote claude here on the fix:
In shapes3d.scad, the module form (line 3872–3876) reads:
rotate_extrude(convexity=4) {
right_half(s=min_rad*2, planar=true)
right(maj_rad)
circle(r=min_rad);
}
The right_half(s=min_rad2) creates a masking rectangle of size min_rad2, centered at the origin. This mask extends from x = 0 to x = min_rad on the positive side. However, the circle is translated to x = maj_rad, so it spans from x = maj_rad - min_rad to x = maj_rad + min_rad.
For any normal ring torus where maj_rad > min_rad, the circle's nearest edge (x = maj_rad - min_rad) is beyond the mask's reach (x = min_rad), so the circle is partially or fully clipped away. The effect worsens as the ratio maj_rad / min_rad increases — for typical use cases (small tube on a large ring), the torus vanishes entirely.
The function form (line 3908–3909) handles this correctly by only applying right_half when it's actually needed (spindle torus case).
For normal ring tori (min_rad <= maj_rad), it skips right_half entirely.
Suggested Fix
Apply the same conditional logic from the function form to the module form:
rotate_extrude(convexity=4) {
if (min_rad <= maj_rad) {
right(maj_rad)
circle(r=min_rad);
} else {
right_half(s=2*(maj_rad+min_rad), planar=true)
right(maj_rad)
circle(r=min_rad);
}
}
Describe the bug
I had some trouble producing a torus also defined by
path_sweep(path=path3d(circle(d=9.5)), shape=circle(d=0.4), closed=true);which should have been possible using
torus(d_maj=9.5, d_min=0.4);But is not - nothing is rendered.
I thought I might have misunderstood the docs and used Claude Opus on the source to figure out if I missed something, and it claimed to have found a bug. I applied the fix and it seems to be at least correct for my case (the fix was previously applied to a function version elsewhere). I found a similar issue with the function version being correct, but the module not - probably a lack of test coverage, but I haven't dug that deep myself.
Let me quote claude here on the fix:
In shapes3d.scad, the module form (line 3872–3876) reads:
The right_half(s=min_rad2) creates a masking rectangle of size min_rad2, centered at the origin. This mask extends from x = 0 to x = min_rad on the positive side. However, the circle is translated to x = maj_rad, so it spans from x = maj_rad - min_rad to x = maj_rad + min_rad.
For any normal ring torus where maj_rad > min_rad, the circle's nearest edge (x = maj_rad - min_rad) is beyond the mask's reach (x = min_rad), so the circle is partially or fully clipped away. The effect worsens as the ratio maj_rad / min_rad increases — for typical use cases (small tube on a large ring), the torus vanishes entirely.
The function form (line 3908–3909) handles this correctly by only applying right_half when it's actually needed (spindle torus case).
For normal ring tori (min_rad <= maj_rad), it skips right_half entirely.
Suggested Fix
Apply the same conditional logic from the function form to the module form: