Open xaqrox opened 3 years ago
So am I just coming up against an inherent limitation in OpenSCAD? Or CGAL? Or is there a better way to model this? Or is there another program that I could model this in...?
Sorry it took so long to respond. Next time show (at least a final) single code snippet with the problem - I was jumping around all your variants...then getting distracted and starting again \:\
For others to reproduce (remove the !
), it gets a CGAL assertion violation:
$fn=12;
thx=20;
long=100;
cubl=200;
difference() {
cube(cubl, center=true);
minkowski() {
difference() {
cube(cubl, center=true);
minkowski() {
// Instead of "lattice();" in the previous snippet.
!for(a=[0, 30]) // 90 works
rotate([0, a, 0])
cylinder(d=thx, h=long, center=true);
sphere(d=thx);
}
}
sphere(d=thx);
}
}
ERROR: CGAL error in CGAL_...
is failure of object integrity when CGAL is processing the various stages of its calculations, something internally 'must' match, but doesn't. Like Expr: e_below != SHalfedge_handle()
says the edge below (whatever that is) should match the edge in the halfedge it is also dealing with.
Ideally OpenSCAD should pass valid geometry to CGAL. Most such errors are from poorly formed import()
ed STLs, or badly built polygons/polyhedrons. Once those are eliminated, it gets messy.
Valid geometry must be manifold (discussion), and have no self-intersections (see diagrams).
When you operate on 'curved' objects, the lines making the edges can sometimes end up aligned (or a common point). These are non manifold. Also some floating point operations can move a point slightly, such that it turns into a self-intersection.
For various reasons this shows its face at inopportune times...
With the !
in the code above, you can see for example, the point in the middle, shared.
It may be that, or some other line; intersecting cylinder()
s tend to be common problems.
Or the first minkowski()
difference()
may introduce another 'point of contention'.
Until someone smarter than me works out a better way internally, I find when this happens you have to jiggle
(TM) the model. As you found, sometimes just fiddling with $fn will make it go away, other times you may need to nudge an object by 0.01 or so.
With intersecting cylinder()
s, I have found rotate()
ing them in Z moves the points they join at enough.
With the code below, this has unaligned points.
Close-up of the middle.
$fn=12;
thx=20;
long=100;
cubl=200;
angles=[0, 30];
difference() {
cube(cubl, center=true);
minkowski() {
difference() {
cube(cubl, center=true);
minkowski() {
// Instead of "lattice();" in the previous snippet.
!for(i=[0,len(angles)-1]) // 90 works
rotate([0, angles[i], i*3.14159])
cylinder(d=thx, h=long, center=true);
sphere(d=thx);
}
}
sphere(d=thx);
}
}
Note you don't always have to be that convoluted, but a simple rotate()
in the original code, rotated both so the points still aligned.
I haven't tried with your lattice, but I suspect a jiggle
(TM) or two to your cylinder()
s will do wonders.
Oops, that rotate had side effects. Try
for(i=[0,len(angles)-1]) // 90 works
rotate([0, angles[i], 0])
rotate([0,0,i*3.14159])
cylinder(d=thx, h=long, center=true);
That too 30 minutes to render, so your lattice will be looong.
There are other fillet approaches, but they don't work with for()
as they need children()
.
Status as of 2024-03-24: This is still an issue, both with CGAL and Manifold
Status as of 2024-09-19: This seems to work fine with Manifold now. Still broken with CGAL.
So I have this object (it's going to be a speaker mount):
Inspired by Irev-Dev/Round-Anything, I want to "fillet" or "round" the sharp boundaries of where the capsule hulls intersect each other. So I'm trying this double-minkowski-then-difference thing.
When I attempt to preview this, after about 8 minutes I get the following error:
Through process of elimination, I find this happens during the second (outer) minkowski. I imagine something about the complex convexity of this model just totally stumps OpenSCAD, but I don't have the background in the math or the software implementation to identify precisely what limitation I am coming up against.
So, I tried some experiments...
If I just do one "face" (the "top", for example) of this model at
$fn=8
, it works:Nice! But if I bump it to
$fn=12
, I get a different error:With a couple primitive cylinders at
$fn=12
instead, we get beautiful success:This also works with a 45deg rotation:
But not at 30deg:
Or 60deg:
It does work with this thing:
But not this thing:
So am I just coming up against an inherent limitation in OpenSCAD? Or CGAL? Or is there a better way to model this? Or is there another program that I could model this in...?