Long rendering time when using difference() with a lot of objects.

classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

Long rendering time when using difference() with a lot of objects.

maeln
Hello !

In a software I'm developping, I'm trying to use OpenSCAD to generate a
3D model of one of the parts that the software is computing.

The thing I'm trying to make is usually a big cylinder with a lot of
holes in it (can range from around a hundred holes to a few thousand).

So naively, I did the following to generate it :
  - 1 : draw the "big" cylinder.
  - 2 : draw every hole has a tiny cylinder with the same height has the
big one.
  - 3 : Use difference() with the big cylinder and all the tiny cylinder.

So something like this in OpenSCAD (I've attached an exemple of what my
software generate) :

difference() {
     cylinder(1.000000,400.000000,400.000000,true);
     union() {
         translate([0.000000,0.000000,0.000000]) {
cylinder(1.000000,6.500000,6.500000,true); }
         translate([31.180000,0.000000,0.000000]) {
cylinder(1.000000,6.500000,6.500000,true); }
         translate([-31.180000,0.000000,0.000000]) {
cylinde(1.000000,6.500000,6.500000,true); }
         translate([62.350000,0.000000,0.000000]) {
cylinder(1.000000,6.500000,6.500000,true); }
.......
     }
}

My problem is that, even though the preview works great, when trying to
render the mesh, it can take around half an hour to an hour and a half
to complete, even with a fairly powerful PC and with the last version of
OpenSCAD (2016.01.27).
I tried to tweak around using $fn, $fa and $fs, but the rendering time
is still very long.

So, I was wondering if my method was completly wrong or if there was any
advice you could give me to lower the rendering time.

Faithfully yours,
--
Maël Naccache <[hidden email]>
Président de l'association Rally Point : rallypoint.fr
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

test2.scad (58K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

nophead
It will be much faster if you do it in 2D with circles and then linear_extrude it to make the cylinder.


On 2 March 2016 at 08:29, Maël Naccache <[hidden email]> wrote:
Hello !

In a software I'm developping, I'm trying to use OpenSCAD to generate a 3D model of one of the parts that the software is computing.

The thing I'm trying to make is usually a big cylinder with a lot of holes in it (can range from around a hundred holes to a few thousand).

So naively, I did the following to generate it :
 - 1 : draw the "big" cylinder.
 - 2 : draw every hole has a tiny cylinder with the same height has the big one.
 - 3 : Use difference() with the big cylinder and all the tiny cylinder.

So something like this in OpenSCAD (I've attached an exemple of what my software generate) :

difference() {
    cylinder(1.000000,400.000000,400.000000,true);
    union() {
        translate([0.000000,0.000000,0.000000]) { cylinder(1.000000,6.500000,6.500000,true); }
        translate([31.180000,0.000000,0.000000]) { cylinder(1.000000,6.500000,6.500000,true); }
        translate([-31.180000,0.000000,0.000000]) { cylinde(1.000000,6.500000,6.500000,true); }
        translate([62.350000,0.000000,0.000000]) { cylinder(1.000000,6.500000,6.500000,true); }
.......
    }
}

My problem is that, even though the preview works great, when trying to render the mesh, it can take around half an hour to an hour and a half to complete, even with a fairly powerful PC and with the last version of OpenSCAD (2016.01.27).
I tried to tweak around using $fn, $fa and $fs, but the rendering time is still very long.

So, I was wondering if my method was completly wrong or if there was any advice you could give me to lower the rendering time.

Faithfully yours,
--
Maël Naccache <[hidden email]>
Président de l'association Rally Point : rallypoint.fr

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

Ronaldo
In a few tests I tried, the rendering time is almost one third when the hole cylinders have a height greater than the base one. Anyway, avoiding coincident faces in CSG operations is a good practice.

2016-03-02 7:08 GMT-03:00 nop head <[hidden email]>:
It will be much faster if you do it in 2D with circles and then linear_extrude it to make the cylinder.


On 2 March 2016 at 08:29, Maël Naccache <[hidden email]> wrote:
Hello !

In a software I'm developping, I'm trying to use OpenSCAD to generate a 3D model of one of the parts that the software is computing.

The thing I'm trying to make is usually a big cylinder with a lot of holes in it (can range from around a hundred holes to a few thousand).

So naively, I did the following to generate it :
 - 1 : draw the "big" cylinder.
 - 2 : draw every hole has a tiny cylinder with the same height has the big one.
 - 3 : Use difference() with the big cylinder and all the tiny cylinder.

So something like this in OpenSCAD (I've attached an exemple of what my software generate) :

difference() {
    cylinder(1.000000,400.000000,400.000000,true);
    union() {
        translate([0.000000,0.000000,0.000000]) { cylinder(1.000000,6.500000,6.500000,true); }
        translate([31.180000,0.000000,0.000000]) { cylinder(1.000000,6.500000,6.500000,true); }
        translate([-31.180000,0.000000,0.000000]) { cylinde(1.000000,6.500000,6.500000,true); }
        translate([62.350000,0.000000,0.000000]) { cylinder(1.000000,6.500000,6.500000,true); }
.......
    }
}

My problem is that, even though the preview works great, when trying to render the mesh, it can take around half an hour to an hour and a half to complete, even with a fairly powerful PC and with the last version of OpenSCAD (2016.01.27).
I tried to tweak around using $fn, $fa and $fs, but the rendering time is still very long.

So, I was wondering if my method was completly wrong or if there was any advice you could give me to lower the rendering time.

Faithfully yours,
--
Maël Naccache <[hidden email]>
Président de l'association Rally Point : rallypoint.fr

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

jpmendes
Hello,

You may try something like this:

//parametric code

DefaultSides=16;
nLines=10;
nCols=50;
hPitch=10;
vPitch=10;
Dout=6;
Din=0;
Sides=24;
cHeight=1;
tHeight=cHeight+2;
Angl=360;
cRad = (nLines <= nCols)? (nCols*hPitch+4*hPitch)/2 : (nLines*vPitch+4*vPitch)/2;

module Tube(Length,Dout,Din,Sides,Angl)  // render(convexity=4)
{
  NSides= (Sides < 3 || Sides==undef)  ?  DefaultSides : Sides;
  rotate_extrude( angle=Angl, convexity=4, $fn=NSides )
    translate([Din/2,0,0])
      square([(Dout-Din)/2,Length]);
}

module MultiTubes()
{
  for (i=[0:nLines-1]){
    for (j=[0:nCols-1]){
        shift=ceil(j/2)-floor(j/2);
        translate([j*hPitch,i*vPitch+shift*(hPitch/2),cHeight/2-1]) Tube(tHeight,Dout,Din,Sides,Angl);
    }
  }
}

//MultiTubes();

module PerfuratedCylinder() render(convexity=10)
{
  difference(){
    translate([(nCols-1)*hPitch/2,(nLines-1)*vPitch/2, cHeight/2]) cylinder(h=cHeight, r=cRad, $fn=48);
    MultiTubes();
  }
}
PerfuratedCylinder();

//end code

Cheers
jpmendes
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

maeln
In reply to this post by nophead
Le 2016-03-02 11:08, nop head a écrit :
> It will be much faster if you do it in 2D with circles and then
> linear_extrude it to make the cylinder.

I tried your solution. Using circle make it way faster, but when I do
the linear_extrude,
it take nearly the same amount of time has my previous method :/ .

Le 2016-03-02 17:43, Ronaldo Persiano a écrit :
> In a few tests I tried, the rendering time is almost one third when
> the hole cylinders have a height greater than the base one. Anyway,
> avoiding coincident faces in CSG operations is a good practice.

Thanks for the tips :) !

Le 2016-03-03 02:13, jpmendes a écrit :

> Hello,
>
> You may try something like this:
>
> //parametric code
>
> DefaultSides=16;
> nLines=10;
> nCols=50;
> hPitch=10;
> vPitch=10;
> Dout=6;
> Din=0;
> Sides=24;
> cHeight=1;
> tHeight=cHeight+2;
> Angl=360;
> cRad = (nLines <= nCols)? (nCols*hPitch+4*hPitch)/2 :
> (nLines*vPitch+4*vPitch)/2;
>
> module Tube(Length,Dout,Din,Sides,Angl)  // render(convexity=4)
> {
>   NSides= (Sides < 3 || Sides==undef)  ?  DefaultSides : Sides;
>   rotate_extrude( angle=Angl, convexity=4, $fn=NSides )
>     translate([Din/2,0,0])
>       square([(Dout-Din)/2,Length]);
> }
>
> module MultiTubes()
> {
>   for (i=[0:nLines-1]){
>     for (j=[0:nCols-1]){
> shift=ceil(j/2)-floor(j/2);
> translate([j*hPitch,i*vPitch+shift*(hPitch/2),cHeight/2-1])
> Tube(tHeight,Dout,Din,Sides,Angl);
>     }
>   }
> }
>
> //MultiTubes();
>
> module PerfuratedCylinder() render(convexity=10)
> {
>   difference(){
>     translate([(nCols-1)*hPitch/2,(nLines-1)*vPitch/2, cHeight/2])
> cylinder(h=cHeight, r=cRad, $fn=48);
>     MultiTubes();
>   }
> }
> PerfuratedCylinder();
>
> //end code
>
> Cheers
> jpmendes

Thanks, I will try it.
--
Maël Naccache <[hidden email]>
Président de l'association Rally Point : rallypoint.fr

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

cacb
On 2016-03-03 08:45, Maël Naccache wrote:
> Using circle make it way faster, but when I do
> the linear_extrude,
> it take nearly the same amount of time has my previous method :/ .

Do you have a more complete example of your code that takes a long time?
I may want to experiment. Is it just a question of subtracting a lot of
small cylinders from a large one?

Carsten Arnholm

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

maeln
Le 2016-03-03 11:05, [hidden email] a écrit :
> Do you have a more complete example of your code that takes a long
> time? I may want to experiment. Is it just a question of subtracting a
> lot of small cylinders from a large one?
>
> Carsten Arnholm

I've attached two exemple that takes a long time to render.
The first one (circle_extrude1.scad) use nophead idea (circles then
lines_extrude),
the second one (cylinder_higher1.scad) use Ronaldo tip (the cylinder for
the hole have a height superior to the main cylinder).

Yep, that's just it, I want to substract a lot of small cylinders (who
share the same size) from a big one.
--
Maël Naccache <[hidden email]>
Président de l'association Rally Point : rallypoint.fr
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

circle_extrude1.scad (42K) Download Attachment
cylinder_higher1.scad (121K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

cacb
On 2016-03-03 11:39, Maël Naccache wrote:
> I've attached two exemple that takes a long time to render.

Thanks. However, it seems your attachments didn't make it through (or
there is something wrong with my mail reader).

> Yep, that's just it, I want to substract a lot of small cylinders (who
> share the same size) from a big one.

Ok, that's easy enough to simulate directly, i will give it a go.

Regards
Carsten Arnholm

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

nophead
I found circle_extrude1.scad to be instantaneous for F6 in OpenScad2015.05.16 (git e673fff) .

Total rendering time: 0 hours, 0 minutes, 0 seconds

Top level object is a 3D object:

Facets: 59016


The reason is it doesn't use GCAL for 2D or linear extrude.



Are you using an old version of OpenScad? It used to use GCAL for 2D.





On 3 March 2016 at 13:00, <[hidden email]> wrote:
On 2016-03-03 11:39, Maël Naccache wrote:
I've attached two exemple that takes a long time to render.

Thanks. However, it seems your attachments didn't make it through (or there is something wrong with my mail reader).

Yep, that's just it, I want to substract a lot of small cylinders (who
share the same size) from a big one.

Ok, that's easy enough to simulate directly, i will give it a go.

Regards

Carsten Arnholm

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

maeln
Le 2016-03-03 14:00, [hidden email] a écrit :
> On 2016-03-03 11:39, Maël Naccache wrote:
>> I've attached two exemple that takes a long time to render.
>
> Thanks. However, it seems your attachments didn't make it through (or
> there is something wrong with my mail reader).

Everything seems ok on my side, but I've pasted them just in case :
http://paste.ubuntu.com/15273519/ - circle_extrude1.scad.
http://paste.ubuntu.com/15273525/ - cylinder_higher1.scad.

Le 2016-03-03 14:24, nop head a écrit :

> I found circle_extrude1.scad to be instantaneous for F6 in
> OpenScad2015.05.16 (git e673fff) .
>
> Total rendering time: 0 hours, 0 minutes, 0 seconds
>
>  Top level object is a 3D object:
>
>  Facets: 59016
>
> The reason is it doesn't use GCAL for 2D or linear extrude.
>
> ​
>
> Are you using an old version of OpenScad? It used to use GCAL for 2D.

Oops, sorry, forgot to mention that I do most of my test on the version
2014.03 (I only have access to this version at work, but I can probably
update it), when I get back home, I will try your solution. Thanks :) !
--
Maël Naccache <[hidden email]>
Président de l'association Rally Point : rallypoint.fr

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

jpmendes
This post was updated on .
Hey,

for 500 holes my code took 8:45 min to render in a dual core old machine.
I know your process is based on previous calculations possible by another program and maybe your approach should be different than mine. Nevertheless half an hour vs. 8:45 is a significant improvement.
 


And thanks nophead for the circle.extrude solution that I found to be almost instantaneous also with the latest OpenScad snapshots. Always learning :)
 
Cheers,
jpmendes
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

cacb
In reply to this post by maeln
On 03. mars 2016 15:08, Maël Naccache wrote:

> Le 2016-03-03 14:00, [hidden email] a écrit :
>> On 2016-03-03 11:39, Maël Naccache wrote:
>>> I've attached two exemple that takes a long time to render.
>>
>> Thanks. However, it seems your attachments didn't make it through (or
>> there is something wrong with my mail reader).
>
> Everything seems ok on my side, but I've pasted them just in case :
> http://paste.ubuntu.com/15273519/ - circle_extrude1.scad.
> http://paste.ubuntu.com/15273525/ - cylinder_higher1.scad.
Thank you, it was my web mail reader that messed it up. I could see the
original attachments just fine when using Thunderbird.

I have done the experiments mentioned now, some relevant files are
attached in the .7z file:

cylinder_higher1.scad : Your original .scad file
mael_cylinder.as : Your file translated to AngelScript CSG
mael_cylinder_CARVE.csg : OpenSCAD .csg file produced, see below
mael_cylinder_CGAL.csg  : OpenSCAD .csg file produced, see below

I am using OpenSCAD 2015.03-2 in these tests, all running on a Windows 7
desktop, approx 5 years old.

TEST A: Your cylinder_higher1.scad displayed with F6. It took just over
13.5 minutes and the final result was somewhat imprecise, i.e. the large
cylinder had visible linear segments.

cylinder_higher1.scad
    -> OpenSCAD (F6)   (~13.5 minutes)
       (large cylinder imprecise)

TEST B1: Your original .scad file translated into AngelScript CSG and an
OpenSCAD .csg file was produced from it. Slight editing of the file
($fs=1.0 globally and $fn=360 for the big cylinder) made the resolution
better than the original in TEST A. Displaying this file with OpenSCAD
F6 took 14 minutes.

mael_cylinder.as
    -> AngelScript CSG (~7 sec)
    -> mael_cylinder_CGAL.csg
    -> OpenSCAD (F6)   (~14 minutes)
       
TEST B2: Here an experimental feature is tested, starting from the same
AngelScript CSG file as in test B1. An experimental file format (.xcsg)
is produced and further processed by a program called xcsg, xcsg
processing is based on the CARVE library to do boolean operations. xcsg
will be released on GitHub when ready. Processing the data with
xcsg/carve took 5 minutes and used no more than 200MB ram. The result
was written to an OpenSCAD .csg file as a complex polyhedron, see the
attached file.
       
mael_cylinder.as
    -> AngelScript CSG (~7 sec)
    -> mael_cylinder.xcsg      (experimental)
    -> xcsg (CARVE)    (5 min) (experimental)
    -> mael_cylinder_CARVE.csg (polyhedron result)
    -> OpenSCAD (F6)   (10 sec)
                                       
The resolution of the B2 result is largely comparable to B1, so these
results can offer at least a rough indication of how CARVE compares to
CGAL wrt. speed and memory requirements. By reducing the resolution
somewhat, the xcsg/carve processing time is further reduced significantly.

Carsten Arnholm


                                       

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

mael_cylinder.7z (519K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

Neon22
In reply to this post by nophead
The offical release is 2015.03-2 on Windows.
Is it time for a new release for 2015.05.16 ?

8hours vs 0 seconds seems like maybe it might be ??

http://www.openscad.org/downloads.html
tp3
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

tp3
On 03/03/2016 10:40 PM, Neon22 wrote:
> The offical release is 2015.03-2 on Windows.
> Is it time for a new release for 2015.05.16 ?
>
> 8hours vs 0 seconds seems like maybe it might be ??
>
Where's that calculation coming from?

The 2015.03-2 patch release is from November 2015

Both that version and the nightly build need 0 seconds
for the 2D + linear-extrude example posted (the file
named circle_extrude1.scad).

A new release would be nice, but there's no chance to be
faster than 0 seconds ;-).

ciao,
  Torsten.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

nophead
How does that compare with 2015.05.16 (git e673fff) that I am using?

On 3 March 2016 at 22:01, Torsten Paul <[hidden email]> wrote:
On 03/03/2016 10:40 PM, Neon22 wrote:
> The offical release is 2015.03-2 on Windows.
> Is it time for a new release for 2015.05.16 ?
>
> 8hours vs 0 seconds seems like maybe it might be ??
>
Where's that calculation coming from?

The 2015.03-2 patch release is from November 2015

Both that version and the nightly build need 0 seconds
for the 2D + linear-extrude example posted (the file
named circle_extrude1.scad).

A new release would be nice, but there's no chance to be
faster than 0 seconds ;-).

ciao,
  Torsten.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
tp3
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

tp3
On 03/03/2016 11:22 PM, nop head wrote:
> How does that compare with 2015.05.16 (git e673fff) that I am using?
>
The most critical stuff was some crash fixes, I think.

List of changes should be:
https://github.com/openscad/openscad/compare/master@%7B2015-05-16%7D...openscad-2015.03-2

So if you get crashes with some model, try the release version,
otherwise it probably will not make much difference.

ciao,
  Torsten.



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

Parkinbot
This post has NOT been accepted by the mailing list yet.
In reply to this post by nophead
nophead wrote
I found circle_extrude1.scad to be instantaneous for F6 in
OpenScad2015.05.16 (git e673fff) .

Total rendering time: 0 hours, 0 minutes, 0 seconds

Top level object is a 3D object:

Facets: 59016
I can confirm this: Instant F6 result, exportable, sliceable ...
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

stonysmith
I know this is off-topic for the "speed" issue, but I wanted to offer a simpler way to generate the holes.

They're not hex-aligned like the examples above, but it still looks cool.

module PAT(){
outer_D=400.0;
inner_D=6.5;
offset=2.5;// adjust for space between rings
theta=6; // adjust for space between holes around rings
linear_extrude(50.0)
difference() { circle(outer_D,center=true,$fn=512);
union() {
circle(inner_D,center=true);
for (j=[1:floor(outer_D/(inner_D*offset))])
  for (i=[1:theta*j]) rotate([0,0,360/(theta*j)*i])
    translate([inner_D*offset*j,0.0,0.0])
    circle(inner_D,center=true);
}}

}
$fa = 12;
$fs = 1;
PAT();
Reply | Threaded
Open this post in threaded view
|

Re: Long rendering time when using difference() with a lot of objects.

Neon22
or go for honeycombs:

module PAT()  {
        outer_D = 400.0;
        inner_D = 6.5;
        height  = 50;
        offset = 2;    // adjust for space between rings
        theta = 6;       // adjust for space between holes around rings
        linear_extrude(h=height)
                // make it all in 2D and extrude the result
                difference() {
                        // disk
                        circle(outer_D,center=true,$fn=512);
                        // holes
                        union() {
                                circle(inner_D, center=true);
                                circle_count = floor(outer_D / (inner_D*offset));
                                for (j = [1:circle_count])
                                        for (i = [1:theta*j])
                                                rotate([0,0,360/(theta*j)*i])
                                                translate([inner_D*offset*j,0,0])
                                                        circle(inner_D, center=true);
                        }
                }
}

// $fa = 12;
// $fs = 1;
$fn=6;
PAT();