Discussion:
[OpenSCAD] too many hexagons crashes openscad (how many is too many?)
wb
2018-10-28 15:10:35 UTC
Permalink
I am a complete beginner trying to build a somewhat unusual object.
I would like to 3D print in metal a thin sheet with 100,000 hexagons on top
of it.
However, once I go past 20,000 object openscad crashes every time.

This is my code so far:

union() {

cube([600,400,2.5]);

for (x = [2:2:200], // <--- I WANT TO INCREASE THIS VALUE to 600
y = [2:2:200]) // <--- I WANT TO INCREASE THIS VALUE to 400
// ((x/2)%2) to alternate even and odd rows
translate([x,y+1*((x/2)%2),2.5]){
color([0.2,0.8,1])
// rotate([0,0,15*y])
cylinder($fn = 6, h = 1, r1 = 1.15, r2 = 1, center = true);
}
}

Which produces something like this:
<Loading Image...>

I may be missing something obvious which makes the code take too much
memory. Is there an alternative, or have I hit the limits? Otherwise, does
it simply seem like a limitation from my computer?

Thank you for any guidance.



--
Sent from: http://forum.openscad.org/
Torsten Paul
2018-10-28 15:23:09 UTC
Permalink
This works for me as it stays in 2D for the hexagons and
also forces to collapse each line into a single internal
object with the render() call.

This is dropping the slight slanted sides of the hexagons,
but I wonder if that would even show up on high resolution
printers.

cube([600,400,2.5]);
color([0.2,0.8,1]) linear_extrude(3.5) {
for (x = [2:2:600]) {
render() for(y = [2:2:400]) {
translate([x,y+1*((x/2)%2),2.5]) {
circle($fn = 6, r = 1, center = true);
}
}
}
}

ciao,
Torsten.
Carsten Arnholm
2018-10-29 19:52:03 UTC
Permalink
Post by wb
I am a complete beginner trying to build a somewhat unusual object.
I would like to 3D print in metal a thin sheet with 100,000 hexagons on top
of it.
Out of curiosity, what is this used for? With a metal printer involved
it must be something important, but what?
Post by wb
However, once I go past 20,000 object openscad crashes every time.
I doubt it is possible to create such a huge object with OpenSCAD, it is
simply too big. I played around with my AngelCAD software and could
create it in full size (600x400) with slanted hexagons in about 35
minutes elapsed time on my Kubuntu 18.04 box with 4 CPUs. It took 60599
booleans to do it...

From the link below you can get the .stl (224 MB uncompressed, viewable
in MeshLab) and also a generated OpenSCAD .csg defining a single
polyhedron of the same. However, I think trying to open the .csg with
OpenSCAD will bring any machine to its knees ....

http://www.fileconvoy.com/dfl.php?id=g7c904f0dcbc03e911000125129f68a355dd0fa9603

adv_hexagon2.7z (13.758 MB)
the download expires in 21 days

Carsten Arnholm
Parkinbot
2018-11-01 09:42:45 UTC
Permalink
it shouldn't be to difficult to generate by using a "lazy union" of X*Y
hexagon cylinders into a single polyhedron call and union that with the
cube.



--
Sent from: http://forum.openscad.org/
a***@arnholm.org
2018-11-01 10:35:10 UTC
Permalink
Post by Parkinbot
it shouldn't be to difficult to generate by using a "lazy union" of X*Y
hexagon cylinders into a single polyhedron call and union that with the
cube.
The file I linked to contains a single polyhedron in an OpenSCAD .csg
file (in addition to the STL). A good first test is to try to open that
file in OpenSCAD, but I have not been successful doing that as it
consumed all machine resources without finishing. It would surprise me
if you could compute it in OpenSCAD (lazy or not), but I am willing to
be surprised :-)

Carsten Arnholm
Parkinbot
2018-11-02 00:39:34 UTC
Permalink
Carsten, you might want to increase your CGAL and polyset cache. I screwed
mine up to 400MB, which lets me construct even an 600x400 array.
The approach is straight forward: calc a single cylinder, file X*Y shifted
copies into a list and feed the right parts into a polyhedron. CFG (f5)
takes 47s on my notebook, CGAL (f6) needs its time, as we know, about 60 min
on my machine. I can export an STL.

X=300;
Y=200;
c=cyl();

cList = [for(x=[0:X-1], y=[0:Y-1]) shift(c, (x*Y+y)*12,
[1+x*2+(y+1)%2*1,1+y*2,2.5])];

polyhedron(filter(cList,0), filter(cList,1));
cube([601,400,2.5]);


function cyl(r1=1.15, r2=1,h=1) =
[concat(cyl2(r1), cyl2(r2,h)), // points
[[5,4,3,2,1,0],[6,7,8,9,10,11], // verts
for(i=[0:5]) [0+i,(1+i)%6,6+(1+i)%6],
for(i=[0:5]) [i,6+(1+i)%6,6+i]]]; // verts

function cyl2(r=1,h=0,n=6) = [for(i=[0:n-1])
r*[sin(i*360/n),cos(i*360/n),h]];

function offs(L, i) = [for(x=L) [for(y=x) y+i]];

function T_(L, v) = [for(p=L) p+v];

function shift(obj, offs=0, t=[0,0,0]) = [T_(obj[0],t), offs(obj[1],offs)];

function filter(L,j) = [for(v=L) for(w=v[j]) w];



--
Sent from: http://forum.openscad.org/
wb
2018-11-02 01:03:25 UTC
Permalink
@Torsten, thank you for the suggestion. Your code runs on my machine ... but
I have not tried to render it. I'm trying to understand why 2D + extrude has
better performance than what I wrote.

@Carsten, "must be something important" is kind of relative. It is an
art-piece I would like to make which represents (in a more or less abstract
way) the columns in the neo-cortex (the outer layer of the brain which has
roughly the surface area and width of this sheet).

@Parkinbot, thanks for the feedback. Will read up on lazy union, CGAL and
polyset cache and will try to understand your script.





--
Sent from: http://forum.openscad.org/
Parkinbot
2018-11-02 08:41:36 UTC
Permalink
The cache argument should be clear. OpenSCAD needs enough memory to be able
to calculate your design. CSG (f5) is fast and tricky, as it displays a
design only in the graphics card. CGAL (f6) is used when it comes to
rendering for STL export. Rendering gets slower and slower the more boolean
operations are involved. Your design is a very extrem case, which will take
years and years due to its complexity.

The lazy union approach is a somehow tricky "peek and poke" technique that
can be used by people who know what they do whenever it comes to a union of
a large number of objects that *do not intersect* by design. Avoiding
intersection checking speeds up things dramatically, but it has its price.
You can't profit from OpenSCAD's geometric primitives (cylinder in your
case) any more, as it requires you to construct as many simple objects as
possible by as little polyhedron calls as possible in an affine way.
I.e. for every nonintersecting group of objects you calculate a list of 3D
points and a list of faces and do the "rendering", which is trivial when
objects don't intersect, yourself by construcing the union with one large
polyhedron. In your case all the little hexagon cylinders can be lazy
unioned, while the union with the cube is more or less unavoidable (you also
could do it yourself, but this is too much work) and must be done by CGAL,
which costs most (99%) of time.
My code constructs a single hexagon cylinder cyl() in an affine way and uses
that as a template to compose a list of cylinders, which is finally stuffed
into a simple polyhedron call. I admit the code is a bit tricky, as it is
dense. But if you know what is does (compose one big polyhedron call for all
the little objects) you should find your way through.



--
Sent from: http://forum.openscad.org/
a***@arnholm.org
2018-11-02 09:11:34 UTC
Permalink
Post by Parkinbot
Carsten, you might want to increase your CGAL and polyset cache. I screwed
mine up to 400MB, which lets me construct even an 600x400 array.
The approach is straight forward: calc a single cylinder, file X*Y shifted
copies into a list and feed the right parts into a polyhedron. CFG (f5)
takes 47s on my notebook, CGAL (f6) needs its time, as we know, about 60 min
on my machine. I can export an STL.
Parkinbot, those are good points, thanks. However, I was creating the
slanted hexagons in my code (where calculations are based on Carve
instead of CGAL) according to the "original spec". After seeing your
response, I realized I had a couple of bugs affecting the calculations.
First, the hexagons were oriented 90 degrees wrong in my case, causing
far too many intersections. Second, my polygon sweep generated far to
many triangles for something simple like this. The result was a much
bigger model than required. After fixing that, the booleans in Carve
(equivalent to CGAL F6 in OpenSCAD) take 2 min 40 sec on a Win10 desktop
for the 600x400 array. However, it should be said that after the
booleans complete I am left with many non-triangular faces and
triangulating them takes time. Triangulation takes 8 minutes 30 seconds
in this case (I am going to investigate speeding it up). All in all from
start to finished file export (4 formats) it takes 12.5 minutes,
generating 738132 vertices and 1476058 faces.

I will check out reading it into OpenSCAD later.

Carsten Arnholm
Parkinbot
2018-11-02 11:22:29 UTC
Permalink
I did a full run while having breakfast. F6 took 95 minutes. The export
produced a 232MB STL and took about 2 minutes to execute. I think you can't
get much faster within the scope of current single threaded OpenSCAD.

<Loading Image...>



--
Sent from: http://forum.openscad.org/
a***@arnholm.org
2018-11-02 13:45:04 UTC
Permalink
Post by Parkinbot
I did a full run while having breakfast. F6 took 95 minutes. The export
produced a 232MB STL and took about 2 minutes to execute. I think you can't
get much faster within the scope of current single threaded OpenSCAD.
That is a big file. The one I created is 70 MB (binary STL).
http://www.fileconvoy.com/dfl.php?id=gf0b9d3183adfc0cd10001262478afc1a139ca26919

Carsten Arnholm
Parkinbot
2018-11-02 17:33:59 UTC
Permalink
Oh, sorry F6 took 75 minutes of course.
OpenSCAD doesn't support writing out binary STLs, a simple option many of us
are waiting for.




--
Sent from: http://forum.openscad.org/
Carsten Arnholm
2018-11-02 20:44:56 UTC
Permalink
Post by Parkinbot
Oh, sorry F6 took 75 minutes of course.
OpenSCAD doesn't support writing out binary STLs, a simple option many of us
are waiting for.
Right, binary STL is a must. Here is some inspiration
https://github.com/arnholm/xcsg/blob/master/xcsg/out_triangles.cpp

look for "write_stl_binary". You will have to replace things related to
carve with equivalent CGAL

Carsten Arnholm

Loading...