discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Complex model - reducing render time

A
adrianv
Fri, Apr 9, 2021 4:44 PM

The problem with many copies of an object is that union is slow.  Even when
the objects are disjoint, finding that they are disjoint takes a long time
(consider checking all pairs of 100 objects).  If you are trying to make a
model of hundreds of these things and they are actually not intersecting (a
model with hundreds of distinct parts) then using lazy union could make it
much faster.  (That's an experimental feature in the dev version.)  It will
output copies of the parts without checking whether they intersect.

When you make copies of one object the information is cached---OpenSCAD
isn't generating the object anew each time.  So importing the part from an
STL will not help.  The only thing I can think of that would help would be
constructing your model to be a smaller number of polyhedra.  But I can't
comment on how that might be done without more information on your full
model.

sasa wrote

Folks,

Thanks so much for your help.

I've implemented both the hull() and the sweep() methods and both work but
the
sweep is fastest.  I'd never seen this library before but it does
<exactly>

what I wanted.

One final question: my final model has many (100s) repeats of this simple
shape and, even with the sweep() method the final render is very slow (how
slow I don't know yet but the memory requirements seem sane).

At the moment I'm saving my shape to .stl and then tiling this .stl file.
Perhaps with the sweep() function I should skip this step? Clearly I need
to
benchmark both approaches but while I wait for the final render would
anyone
care to guess which would be faster?

Thanks!


OpenSCAD mailing list
To unsubscribe send an email to

discuss-leave@.openscad

The problem with many copies of an object is that union is slow. Even when the objects are disjoint, finding that they are disjoint takes a long time (consider checking all pairs of 100 objects). If you are trying to make a model of hundreds of these things and they are actually not intersecting (a model with hundreds of distinct parts) then using lazy union could make it much faster. (That's an experimental feature in the dev version.) It will output copies of the parts without checking whether they intersect. When you make copies of one object the information is cached---OpenSCAD isn't generating the object anew each time. So importing the part from an STL will not help. The only thing I can think of that would help would be constructing your model to be a smaller number of polyhedra. But I can't comment on how that might be done without more information on your full model. sasa wrote > Folks, > > Thanks so much for your help. > > I've implemented both the hull() and the sweep() methods and both work but > the > sweep is fastest. I'd never seen this library before but it does > <exactly> > > what I wanted. > > One final question: my final model has many (100s) repeats of this simple > shape and, even with the sweep() method the final render is very slow (how > slow I don't know yet but the memory requirements seem sane). > > At the moment I'm saving my shape to .stl and then tiling this .stl file. > Perhaps with the sweep() function I should skip this step? Clearly I need > to > benchmark both approaches but while I wait for the final render would > anyone > care to guess which would be faster? > > Thanks! > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to > discuss-leave@.openscad -- Sent from: http://forum.openscad.org/
S
superaorta@gmail.com
Fri, Apr 9, 2021 6:06 PM

model with hundreds of distinct parts) then using lazy union could make it
much faster.  (That's an experimental feature in the dev version.)  It will
output copies of the parts without checking whether they intersect.

I'm sure that willmake things much faster...

When you make copies of one object the information is cached---OpenSCAD
isn't generating the object anew each time.  So importing the part from an

What do you mean "make copies" I'm just generating (or loading) 300 identical
versions of the same object...

> model with hundreds of distinct parts) then using lazy union could make it > much faster. (That's an experimental feature in the dev version.) It will > output copies of the parts without checking whether they intersect. I'm sure that willmake things much faster... > When you make copies of one object the information is cached---OpenSCAD > isn't generating the object anew each time. So importing the part from an What do you mean "make copies" I'm just generating (or loading) 300 identical versions of the same object...
A
adrianv
Fri, Apr 9, 2021 9:09 PM

If you have 300 non-intersecting copies of the same object then lazy  union
should work for you.  It might also work to make one polyhedron with all 300
objects in it instead of 300 polyhedra.  (I haven't tried this.)  You still
didn't actually reveal your end goal.

If you're trying to make hair on a sphere or something it's not so easy,
because everything actually intersects.

When I say make copies I mean just what I said:  you have the same object in
your model multiple times.  Unless the time to compute your model for a
single object is very long, you're not going to gain anything by saving it
to stl and reloading it because the object is only actually calculated or
loaded one time, and then the copying is the same no matter whether you
calculated it or loaded it.  (It's also a very ugly method, so I'd say it
better deliver a big advantage if you are going to do it.)

sasa wrote

model with hundreds of distinct parts) then using lazy union could make
it
much faster.  (That's an experimental feature in the dev version.)  It
will
output copies of the parts without checking whether they intersect.

I'm sure that willmake things much faster...

When you make copies of one object the information is cached---OpenSCAD
isn't generating the object anew each time.  So importing the part from
an

What do you mean "make copies" I'm just generating (or loading) 300
identical
versions of the same object...


OpenSCAD mailing list
To unsubscribe send an email to

discuss-leave@.openscad

If you have 300 non-intersecting copies of the same object then lazy union should work for you. It might also work to make one polyhedron with all 300 objects in it instead of 300 polyhedra. (I haven't tried this.) You still didn't actually reveal your end goal. If you're trying to make hair on a sphere or something it's not so easy, because everything actually intersects. When I say make copies I mean just what I said: you have the same object in your model multiple times. Unless the time to compute your model for a single object is very long, you're not going to gain anything by saving it to stl and reloading it because the object is only actually calculated or loaded one time, and then the copying is the same no matter whether you calculated it or loaded it. (It's also a very ugly method, so I'd say it better deliver a big advantage if you are going to do it.) sasa wrote >> model with hundreds of distinct parts) then using lazy union could make >> it >> much faster. (That's an experimental feature in the dev version.) It >> will >> output copies of the parts without checking whether they intersect. > > I'm sure that willmake things much faster... > >> When you make copies of one object the information is cached---OpenSCAD >> isn't generating the object anew each time. So importing the part from >> an > > What do you mean "make copies" I'm just generating (or loading) 300 > identical > versions of the same object... > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to > discuss-leave@.openscad -- Sent from: http://forum.openscad.org/
P
Parkinbot
Sun, Apr 11, 2021 11:31 AM

adrianv wrote

If you have 300 non-intersecting copies of the same object then lazy
union
should work for you.  It might also work to make one polyhedron with all
300
objects in it instead of 300 polyhedra.  (I haven't tried this.)

There are at least two different notions of "lazy union":

One is that OpenSCAD will omit to calculate a union in certain situations
and used to be an experimental feature in the dev snapshots dating back to
2019 or so. I think you can't activate it in the release versions.

The other one was discussed in this forum several times in the last years
and aimed on stuffing the point lists and triangles of a number of objects
known to be non-intersecting into the same polyhedron call. This technique
even allows to bypass a CGAL rendering before STL export, given
a) there are no Boolean operations in the code
b) the whole thing is really a proper manifold - i.e. watertight, no
intersecting edges, no common vertices

My Naca_sweep libary (following Ronaldo's ideas who maintains a similar
library) covers the second case and does a fantastic job in constructing
hundreds of objects within a single polyhedron() call. It has a sweeps()
function that combines the dataset for N ordinary sweep operations into a
single dataset to be stuffed into a single polyhedron call.

As a test case for the problem of the TS I quickly composed a lazy union of
100 objects (curved hairs) built of 180 circles each comprising 30 vertices,
as shown in the picture attached. The run time on my system for F5 was 37s,
for F6 only 34s and the export was a 64MB STL file, containing a proper
manifold (that e.g. can be imported to kisslicer).
If anybody is interested please let me know, as I didn't show the details in
favor of compactness.

http://forum.openscad.org/file/t887/multiobj.png

Here the main library part, which shows a quite simple interface

--
Sent from: http://forum.openscad.org/

adrianv wrote > If you have 300 non-intersecting copies of the same object then lazy > union > should work for you. It might also work to make one polyhedron with all > 300 > objects in it instead of 300 polyhedra. (I haven't tried this.) There are at least two different notions of "lazy union": One is that OpenSCAD will omit to calculate a union in certain situations and used to be an experimental feature in the dev snapshots dating back to 2019 or so. I think you can't activate it in the release versions. The other one was discussed in this forum several times in the last years and aimed on stuffing the point lists and triangles of a number of objects *known to be non-intersecting* into the same polyhedron call. This technique even allows to bypass a CGAL rendering before STL export, given a) there are no Boolean operations in the code b) the whole thing is really a proper manifold - i.e. watertight, no intersecting edges, no common vertices My Naca_sweep libary (following Ronaldo's ideas who maintains a similar library) covers the second case and does a fantastic job in constructing hundreds of objects within a single polyhedron() call. It has a sweeps() function that combines the dataset for N ordinary sweep operations into a single dataset to be stuffed into a single polyhedron call. As a test case for the problem of the TS I quickly composed a lazy union of 100 objects (curved hairs) built of 180 circles each comprising 30 vertices, as shown in the picture attached. The run time on my system for F5 was 37s, for F6 only 34s and the export was a 64MB STL file, containing a proper manifold (that e.g. can be imported to kisslicer). If anybody is interested please let me know, as I didn't show the details in favor of compactness. <http://forum.openscad.org/file/t887/multiobj.png> Here the main library part, which shows a quite simple interface -- Sent from: http://forum.openscad.org/
A
adrianv
Sun, Apr 11, 2021 3:53 PM

Yes, the method of making one polyhedron with all the objects in it is easy
enough to execute.  I tried it two ways in BOSL2.  I can sweep a "region"
which is a shape defined by many polygons, or I can joint together
polyhedron data from multiple polyhedra.  If I use sweep directly it is slow
because sweep is not lazy enough---it checks the swept multi-polygon shape
for intersections.  But if I sweep the shape and then just make copies and
gather them into one polyhedron, it is snappy: I can make 100 hairs in 3s.

It looks like in your test you didn't use the original point list, but a
different larger list of points.  I tried also making the hairs 180 circles
long and my run time stretches to 20s.  Render was 21s.  Full code with all
details included below.

My presumption is that this isn't what the original poster is actually
trying to do...that his hairs are connected to something, which makes the
problem more difficult.

include<BOSL2/std.scad>

$fn=30;
pts = [
[0.000000,0,10.593750],
[0.000000,0,10.406250],
[-0.003906,0,10.199219],
[-0.011719,0,9.972656],
[-0.023438,0,9.726562],
[-0.039062,0,9.460938],
[-0.058594,0,9.175781],
[-0.082031,0,8.871094],
[-0.109375,0,8.546875],
[-0.140625,0,8.203125],
[-0.175781,0,7.839844],
[-0.214844,0,7.457031],
[-0.257812,0,7.054688],
[-0.304688,0,6.632812],
[-0.355469,0,6.191406],
[-0.410156,0,5.730469],
[-0.468750,0,5.250000],
[-0.531250,0,4.750000],
[-0.582031,0,4.273438],
[-0.621094,0,3.820312],
[-0.648438,0,3.390625],
[-0.664062,0,2.984375],
[-0.667969,0,2.601562],
[-0.660156,0,2.242188],
[-0.640625,0,1.906250],
[-0.609375,0,1.593750],
[-0.566406,0,1.304688],
[-0.511719,0,1.039062],
[-0.445312,0,0.796875],
[-0.367188,0,0.578125],
[-0.277344,0,0.382812],
[-0.175781,0,0.210938],
[-0.062500,0,0.062500],
];

//pts = [for(i=[1:180]) [sin(i),0,i/18]];

// This method works, but is slow (~2 minutes)
//many_circles = [for(x=[0:9], y=[0:9]) move([x,y],circle(r=.2))];
//path_sweep(many_circles, pts);

// This approach is faster 3.7s
one_hair = path_sweep(circle(r=.2),pts);
many_hairs = vnf_merge([for(x=[0:9], y=[0:9]) move([x,y],one_hair)]);
vnf_polyhedron(many_hairs);

Parkinbot wrote

adrianv wrote

If you have 300 non-intersecting copies of the same object then lazy
union
should work for you.  It might also work to make one polyhedron with all
300
objects in it instead of 300 polyhedra.  (I haven't tried this.)

There are at least two different notions of "lazy union":

One is that OpenSCAD will omit to calculate a union in certain situations
and used to be an experimental feature in the dev snapshots dating back to
2019 or so. I think you can't activate it in the release versions.

The other one was discussed in this forum several times in the last years
and aimed on stuffing the point lists and triangles of a number of objects
known to be non-intersecting into the same polyhedron call. This
technique
even allows to bypass a CGAL rendering before STL export, given
a) there are no Boolean operations in the code
b) the whole thing is really a proper manifold - i.e. watertight, no
intersecting edges, no common vertices

My Naca_sweep libary (following Ronaldo's ideas who maintains a similar
library) covers the second case and does a fantastic job in constructing
hundreds of objects within a single polyhedron() call. It has a sweeps()
function that combines the dataset for N ordinary sweep operations into a
single dataset to be stuffed into a single polyhedron call.

As a test case for the problem of the TS I quickly composed a lazy union
of
100 objects (curved hairs) built of 180 circles each comprising 30
vertices,
as shown in the picture attached. The run time on my system for F5 was
37s,
for F6 only 34s and the export was a 64MB STL file, containing a proper
manifold (that e.g. can be imported to kisslicer).
If anybody is interested please let me know, as I didn't show the details
in
favor of compactness.

<http://forum.openscad.org/file/t887/multiobj.png>

Here the main library part, which shows a quite simple interface

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
To unsubscribe send an email to

discuss-leave@.openscad

Yes, the method of making one polyhedron with all the objects in it is easy enough to execute. I tried it two ways in BOSL2. I can sweep a "region" which is a shape defined by many polygons, or I can joint together polyhedron data from multiple polyhedra. If I use sweep directly it is slow because sweep is not lazy enough---it checks the swept multi-polygon shape for intersections. But if I sweep the shape and then just make copies and gather them into one polyhedron, it is snappy: I can make 100 hairs in 3s. It looks like in your test you didn't use the original point list, but a different larger list of points. I tried also making the hairs 180 circles long and my run time stretches to 20s. Render was 21s. Full code with all details included below. My presumption is that this isn't what the original poster is actually trying to do...that his hairs are connected to something, which makes the problem more difficult. include<BOSL2/std.scad> $fn=30; pts = [ [0.000000,0,10.593750], [0.000000,0,10.406250], [-0.003906,0,10.199219], [-0.011719,0,9.972656], [-0.023438,0,9.726562], [-0.039062,0,9.460938], [-0.058594,0,9.175781], [-0.082031,0,8.871094], [-0.109375,0,8.546875], [-0.140625,0,8.203125], [-0.175781,0,7.839844], [-0.214844,0,7.457031], [-0.257812,0,7.054688], [-0.304688,0,6.632812], [-0.355469,0,6.191406], [-0.410156,0,5.730469], [-0.468750,0,5.250000], [-0.531250,0,4.750000], [-0.582031,0,4.273438], [-0.621094,0,3.820312], [-0.648438,0,3.390625], [-0.664062,0,2.984375], [-0.667969,0,2.601562], [-0.660156,0,2.242188], [-0.640625,0,1.906250], [-0.609375,0,1.593750], [-0.566406,0,1.304688], [-0.511719,0,1.039062], [-0.445312,0,0.796875], [-0.367188,0,0.578125], [-0.277344,0,0.382812], [-0.175781,0,0.210938], [-0.062500,0,0.062500], ]; //pts = [for(i=[1:180]) [sin(i),0,i/18]]; // This method works, but is slow (~2 minutes) //many_circles = [for(x=[0:9], y=[0:9]) move([x,y],circle(r=.2))]; //path_sweep(many_circles, pts); // This approach is faster 3.7s one_hair = path_sweep(circle(r=.2),pts); many_hairs = vnf_merge([for(x=[0:9], y=[0:9]) move([x,y],one_hair)]); vnf_polyhedron(many_hairs); Parkinbot wrote > adrianv wrote >> If you have 300 non-intersecting copies of the same object then lazy >> union >> should work for you. It might also work to make one polyhedron with all >> 300 >> objects in it instead of 300 polyhedra. (I haven't tried this.) > > There are at least two different notions of "lazy union": > > One is that OpenSCAD will omit to calculate a union in certain situations > and used to be an experimental feature in the dev snapshots dating back to > 2019 or so. I think you can't activate it in the release versions. > > The other one was discussed in this forum several times in the last years > and aimed on stuffing the point lists and triangles of a number of objects > *known to be non-intersecting* into the same polyhedron call. This > technique > even allows to bypass a CGAL rendering before STL export, given > a) there are no Boolean operations in the code > b) the whole thing is really a proper manifold - i.e. watertight, no > intersecting edges, no common vertices > > My Naca_sweep libary (following Ronaldo's ideas who maintains a similar > library) covers the second case and does a fantastic job in constructing > hundreds of objects within a single polyhedron() call. It has a sweeps() > function that combines the dataset for N ordinary sweep operations into a > single dataset to be stuffed into a single polyhedron call. > > As a test case for the problem of the TS I quickly composed a lazy union > of > 100 objects (curved hairs) built of 180 circles each comprising 30 > vertices, > as shown in the picture attached. The run time on my system for F5 was > 37s, > for F6 only 34s and the export was a 64MB STL file, containing a proper > manifold (that e.g. can be imported to kisslicer). > If anybody is interested please let me know, as I didn't show the details > in > favor of compactness. > > &lt;http://forum.openscad.org/file/t887/multiobj.png&gt; > > Here the main library part, which shows a quite simple interface > > > > > > -- > Sent from: http://forum.openscad.org/ > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to > discuss-leave@.openscad -- Sent from: http://forum.openscad.org/
P
Parkinbot
Sun, Apr 11, 2021 5:28 PM

adrianv wrote

It looks like in your test you didn't use the original point list, but a
different larger list of points.

Well, I didn't want to spend the time to gether the full information about
the hair object from all the posts to be able to show a more adopted
solution, as the TS was a bit vague about how the objects will be situated
in 3D space. And, I don't know, whether the method I showed works out of the
box with BOSL2, since I don't use this lib. But I don't think so.

The method just combines the data of N not necessarily similar skin (or
sweep) operations into a single polyhedron call that is all - no secrets.

When I use your pts-Array (33 vertices) instead of circle() (30 vertices) to
construct the "hair", F5 time is again 37s - no wonder, because the
complexity is about the same. With 200 objects F5 time grows to 1:11

However, to fit into my code setup I had to rotate the "hair" given in pts
...

function obj() =
let (ci = Rx(90, pts))
[for (i = [0:180])
Tz(i, Tx(40*sin(i), ci))
];

I attached my lib if you wanna check yourselves or have a look into the
code.

Naca_sweep.scad http://forum.openscad.org/file/t887/Naca_sweep.scad

--
Sent from: http://forum.openscad.org/

adrianv wrote > It looks like in your test you didn't use the original point list, but a > different larger list of points. Well, I didn't want to spend the time to gether the full information about the hair object from all the posts to be able to show a more adopted solution, as the TS was a bit vague about how the objects will be situated in 3D space. And, I don't know, whether the method I showed works out of the box with BOSL2, since I don't use this lib. But I don't think so. The method just combines the data of N not necessarily similar skin (or sweep) operations into a single polyhedron call that is all - no secrets. When I use your pts-Array (33 vertices) instead of circle() (30 vertices) to construct the "hair", F5 time is again 37s - no wonder, because the complexity is about the same. With 200 objects F5 time grows to 1:11 However, to fit into my code setup I had to rotate the "hair" given in pts ... function obj() = let (ci = Rx(90, pts)) [for (i = [0:180]) Tz(i, Tx(40*sin(i), ci)) ]; I attached my lib if you wanna check yourselves or have a look into the code. Naca_sweep.scad <http://forum.openscad.org/file/t887/Naca_sweep.scad> -- Sent from: http://forum.openscad.org/