BC
Bob Carlson
Tue, Sep 26, 2023 9:02 PM
I’ve been loosely following the thread that discusses lazy unions, but any clear description of the issue has eluded me so far. Can someone explain?
Shortly after starting OpenScad I became (painfully) aware that {x; y; z} is not the same as union() {x; y; z}. It still annoys me though I guess I can see a reason for it. Is the former a “lazy union”? Or is the problem more subtle?
-Bob
Tucson AZ
I’ve been loosely following the thread that discusses lazy unions, but any clear description of the issue has eluded me so far. Can someone explain?
Shortly after starting OpenScad I became (painfully) aware that {x; y; z} is not the same as union() {x; y; z}. It still annoys me though I guess I can see a reason for it. Is the former a “lazy union”? Or is the problem more subtle?
-Bob
Tucson AZ
AM
Adrian Mariano
Tue, Sep 26, 2023 9:17 PM
There are various subtleties with lazy union, but I think the two main
issues are doing hulls and passing children. I'm not sure which are
actually resolved by the current lazy union implementation, because I
recall that it was incomplete.
It would be nice to be able to generate children, e.g. with for(), and pass
them as separate children to a parent. This is impossible because of
automatic unions that happen. So generally speaking there are situations
where you'd like to be able to pass multiple objects and you can't because
they are automatically combined and there's no way to stop it and no way
around it.
In the case of hull, you write hull(){x;y;z} and the union is unnecessarily
computed and then passed to hull(). This is bad because hull() is fast
whereas union can be very slow, so your code can be 10x faster with lazy
union. If I recall correctly, the common strategy of making a rounded cube
by doing the hull of 8 spheres is dramatically faster if you have lazy
unions.
On Tue, Sep 26, 2023 at 5:03 PM Bob Carlson bob@rjcarlson.com wrote:
I’ve been loosely following the thread that discusses lazy unions, but any
clear description of the issue has eluded me so far. Can someone explain?
Shortly after starting OpenScad I became (painfully) aware that {x; y; z}
is not the same as union() {x; y; z}. It still annoys me though I guess I
can see a reason for it. Is the former a “lazy union”? Or is the problem
more subtle?
-Bob
Tucson AZ
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
There are various subtleties with lazy union, but I think the two main
issues are doing hulls and passing children. I'm not sure which are
actually resolved by the current lazy union implementation, because I
recall that it was incomplete.
It would be nice to be able to generate children, e.g. with for(), and pass
them as separate children to a parent. This is impossible because of
automatic unions that happen. So generally speaking there are situations
where you'd like to be able to pass multiple objects and you can't because
they are automatically combined and there's no way to stop it and no way
around it.
In the case of hull, you write hull(){x;y;z} and the union is unnecessarily
computed and then passed to hull(). This is bad because hull() is fast
whereas union can be very slow, so your code can be 10x faster with lazy
union. If I recall correctly, the common strategy of making a rounded cube
by doing the hull of 8 spheres is dramatically faster if you have lazy
unions.
On Tue, Sep 26, 2023 at 5:03 PM Bob Carlson <bob@rjcarlson.com> wrote:
> I’ve been loosely following the thread that discusses lazy unions, but any
> clear description of the issue has eluded me so far. Can someone explain?
>
> Shortly after starting OpenScad I became (painfully) aware that {x; y; z}
> is not the same as union() {x; y; z}. It still annoys me though I guess I
> can see a reason for it. Is the former a “lazy union”? Or is the problem
> more subtle?
>
> -Bob
> Tucson AZ
>
>
>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
NH
nop head
Tue, Sep 26, 2023 9:36 PM
If you place the spheres with 8 individual translates then hull is fast
without lazy union.
On Tue, 26 Sept 2023 at 22:18, Adrian Mariano avm4@cornell.edu wrote:
There are various subtleties with lazy union, but I think the two main
issues are doing hulls and passing children. I'm not sure which are
actually resolved by the current lazy union implementation, because I
recall that it was incomplete.
It would be nice to be able to generate children, e.g. with for(), and
pass them as separate children to a parent. This is impossible because of
automatic unions that happen. So generally speaking there are situations
where you'd like to be able to pass multiple objects and you can't because
they are automatically combined and there's no way to stop it and no way
around it.
In the case of hull, you write hull(){x;y;z} and the union is
unnecessarily computed and then passed to hull(). This is bad because
hull() is fast whereas union can be very slow, so your code can be 10x
faster with lazy union. If I recall correctly, the common strategy of
making a rounded cube by doing the hull of 8 spheres is dramatically faster
if you have lazy unions.
On Tue, Sep 26, 2023 at 5:03 PM Bob Carlson bob@rjcarlson.com wrote:
I’ve been loosely following the thread that discusses lazy unions, but
any clear description of the issue has eluded me so far. Can someone
explain?
Shortly after starting OpenScad I became (painfully) aware that {x; y; z}
is not the same as union() {x; y; z}. It still annoys me though I guess I
can see a reason for it. Is the former a “lazy union”? Or is the problem
more subtle?
-Bob
Tucson AZ
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
If you place the spheres with 8 individual translates then hull is fast
without lazy union.
On Tue, 26 Sept 2023 at 22:18, Adrian Mariano <avm4@cornell.edu> wrote:
> There are various subtleties with lazy union, but I think the two main
> issues are doing hulls and passing children. I'm not sure which are
> actually resolved by the current lazy union implementation, because I
> recall that it was incomplete.
>
> It would be nice to be able to generate children, e.g. with for(), and
> pass them as separate children to a parent. This is impossible because of
> automatic unions that happen. So generally speaking there are situations
> where you'd like to be able to pass multiple objects and you can't because
> they are automatically combined and there's no way to stop it and no way
> around it.
>
> In the case of hull, you write hull(){x;y;z} and the union is
> unnecessarily computed and then passed to hull(). This is bad because
> hull() is fast whereas union can be very slow, so your code can be 10x
> faster with lazy union. If I recall correctly, the common strategy of
> making a rounded cube by doing the hull of 8 spheres is dramatically faster
> if you have lazy unions.
>
> On Tue, Sep 26, 2023 at 5:03 PM Bob Carlson <bob@rjcarlson.com> wrote:
>
>> I’ve been loosely following the thread that discusses lazy unions, but
>> any clear description of the issue has eluded me so far. Can someone
>> explain?
>>
>> Shortly after starting OpenScad I became (painfully) aware that {x; y; z}
>> is not the same as union() {x; y; z}. It still annoys me though I guess I
>> can see a reason for it. Is the former a “lazy union”? Or is the problem
>> more subtle?
>>
>> -Bob
>> Tucson AZ
>>
>>
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
JB
Jordan Brown
Wed, Sep 27, 2023 4:45 AM
On 9/26/2023 2:17 PM, Adrian Mariano wrote:
In the case of hull, you write hull(){x;y;z} and the union is
unnecessarily computed and then passed to hull(). This is bad because
hull() is fast whereas union can be very slow, so your code can be 10x
faster with lazy union. If I recall correctly, the common strategy of
making a rounded cube by doing the hull of 8 spheres is dramatically
faster if you have lazy unions.
No module - built in or user - is required to automatically union its
children.
The problem you're describing is presumably if you use for() to generate
the children, where the hull() will only see one child that has already
been unioned.
On 9/26/2023 2:17 PM, Adrian Mariano wrote:
> In the case of hull, you write hull(){x;y;z} and the union is
> unnecessarily computed and then passed to hull(). This is bad because
> hull() is fast whereas union can be very slow, so your code can be 10x
> faster with lazy union. If I recall correctly, the common strategy of
> making a rounded cube by doing the hull of 8 spheres is dramatically
> faster if you have lazy unions.
No module - built in or user - is required to automatically union its
children.
The problem you're describing is presumably if you use for() to generate
the children, where the hull() will only see one child that has already
been unioned.
CK
Chun Kit LAM
Wed, Sep 27, 2023 8:05 AM
On 9/26/2023 2:17 PM, Adrian Mariano wrote:
In the case of hull, you write hull(){x;y;z} and the union is
unnecessarily computed and then passed to hull(). This is bad because
hull() is fast whereas union can be very slow, so your code can be 10x
faster with lazy union. If I recall correctly, the common strategy of
making a rounded cube by doing the hull of 8 spheres is dramatically
faster if you have lazy unions.
I think the semantics change with lazy union is much more important than
performance associated to lazy union. Performance with this is just an
implementation issue.
-
With manifold backend enabled, hull + union of 8 intersecting
spheres (i.e. cannot skip union on manifold side) with $fn=256
took 1.7s, while hull without union took 1s, which is not dramatically
faster...
-
We can always optimize hull + union without affecting semantics. We
already have a bunch of CSG tree rewriting rules for optimization in
manifold, it is quite trivial to extend them to hull.
I think the name for lazy-union is simply wrong. Laziness will not
change the semantics of a pure functional programming language.
Lazy-union should be renamed into implicit union, which is the real
breaking change. The ability to use for expression to generate a bunch
of stuff and intersect them together is an important usecase, and is
currently impossible to do without 'lazy-union'.
On 9/26/2023 2:17 PM, Adrian Mariano wrote:
> In the case of hull, you write hull(){x;y;z} and the union is
> unnecessarily computed and then passed to hull(). This is bad because
> hull() is fast whereas union can be very slow, so your code can be 10x
> faster with lazy union. If I recall correctly, the common strategy of
> making a rounded cube by doing the hull of 8 spheres is dramatically
> faster if you have lazy unions.
I think the semantics change with lazy union is much more important than
performance associated to lazy union. Performance with this is just an
implementation issue.
1. With manifold backend enabled, hull + union of 8 *intersecting*
spheres (i.e. cannot skip union on manifold side) with $fn=256
took 1.7s, while hull without union took 1s, which is not dramatically
faster...
2. We can always optimize hull + union *without affecting semantics*. We
already have a bunch of CSG tree rewriting rules for optimization in
manifold, it is quite trivial to extend them to hull.
I think the name for lazy-union is simply wrong. Laziness will not
change the semantics of a pure functional programming language.
Lazy-union should be renamed into implicit union, which is the real
breaking change. The ability to use for expression to generate a bunch
of stuff and intersect them together is an important usecase, and is
currently impossible to do without 'lazy-union'.
NH
nop head
Wed, Sep 27, 2023 9:24 AM
There is intersection_for, so it isn't impossible.
On Wed, 27 Sept 2023, 10:21 Chun Kit LAM, john.lck40@gmail.com wrote:
On 9/26/2023 2:17 PM, Adrian Mariano wrote:
In the case of hull, you write hull(){x;y;z} and the union is
unnecessarily computed and then passed to hull(). This is bad because
hull() is fast whereas union can be very slow, so your code can be 10x
faster with lazy union. If I recall correctly, the common strategy of
making a rounded cube by doing the hull of 8 spheres is dramatically
faster if you have lazy unions.
I think the semantics change with lazy union is much more important than
performance associated to lazy union. Performance with this is just an
implementation issue.
-
With manifold backend enabled, hull + union of 8 intersecting
spheres (i.e. cannot skip union on manifold side) with $fn=256
took 1.7s, while hull without union took 1s, which is not dramatically
faster...
-
We can always optimize hull + union without affecting semantics. We
already have a bunch of CSG tree rewriting rules for optimization in
manifold, it is quite trivial to extend them to hull.
I think the name for lazy-union is simply wrong. Laziness will not
change the semantics of a pure functional programming language.
Lazy-union should be renamed into implicit union, which is the real
breaking change. The ability to use for expression to generate a bunch
of stuff and intersect them together is an important usecase, and is
currently impossible to do without 'lazy-union'.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
There is intersection_for, so it isn't impossible.
On Wed, 27 Sept 2023, 10:21 Chun Kit LAM, <john.lck40@gmail.com> wrote:
> On 9/26/2023 2:17 PM, Adrian Mariano wrote:
> > In the case of hull, you write hull(){x;y;z} and the union is
> > unnecessarily computed and then passed to hull(). This is bad because
> > hull() is fast whereas union can be very slow, so your code can be 10x
> > faster with lazy union. If I recall correctly, the common strategy of
> > making a rounded cube by doing the hull of 8 spheres is dramatically
> > faster if you have lazy unions.
>
> I think the semantics change with lazy union is much more important than
> performance associated to lazy union. Performance with this is just an
> implementation issue.
>
> 1. With manifold backend enabled, hull + union of 8 *intersecting*
> spheres (i.e. cannot skip union on manifold side) with $fn=256
> took 1.7s, while hull without union took 1s, which is not dramatically
> faster...
>
> 2. We can always optimize hull + union *without affecting semantics*. We
> already have a bunch of CSG tree rewriting rules for optimization in
> manifold, it is quite trivial to extend them to hull.
>
> I think the name for lazy-union is simply wrong. Laziness will not
> change the semantics of a pure functional programming language.
> Lazy-union should be renamed into implicit union, which is the real
> breaking change. The ability to use for expression to generate a bunch
> of stuff and intersect them together is an important usecase, and is
> currently impossible to do without 'lazy-union'.
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
P
pca006132
Wed, Sep 27, 2023 9:50 AM
If it does not enable more things, and it causes semantics change, should
we remove it? It seems to me that there is no reason to keep it. We can use
some other methods to get better performance without changing the behavior
of existing code.
On Wed, Sep 27, 2023, 5:24 PM nop head nop.head@gmail.com wrote:
There is intersection_for, so it isn't impossible.
On Wed, 27 Sept 2023, 10:21 Chun Kit LAM, john.lck40@gmail.com wrote:
On 9/26/2023 2:17 PM, Adrian Mariano wrote:
In the case of hull, you write hull(){x;y;z} and the union is
unnecessarily computed and then passed to hull(). This is bad because
hull() is fast whereas union can be very slow, so your code can be 10x
faster with lazy union. If I recall correctly, the common strategy of
making a rounded cube by doing the hull of 8 spheres is dramatically
faster if you have lazy unions.
I think the semantics change with lazy union is much more important than
performance associated to lazy union. Performance with this is just an
implementation issue.
-
With manifold backend enabled, hull + union of 8 intersecting
spheres (i.e. cannot skip union on manifold side) with $fn=256
took 1.7s, while hull without union took 1s, which is not dramatically
faster...
-
We can always optimize hull + union without affecting semantics. We
already have a bunch of CSG tree rewriting rules for optimization in
manifold, it is quite trivial to extend them to hull.
I think the name for lazy-union is simply wrong. Laziness will not
change the semantics of a pure functional programming language.
Lazy-union should be renamed into implicit union, which is the real
breaking change. The ability to use for expression to generate a bunch
of stuff and intersect them together is an important usecase, and is
currently impossible to do without 'lazy-union'.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
If it does not enable more things, and it causes semantics change, should
we remove it? It seems to me that there is no reason to keep it. We can use
some other methods to get better performance without changing the behavior
of existing code.
On Wed, Sep 27, 2023, 5:24 PM nop head <nop.head@gmail.com> wrote:
> There is intersection_for, so it isn't impossible.
>
> On Wed, 27 Sept 2023, 10:21 Chun Kit LAM, <john.lck40@gmail.com> wrote:
>
>> On 9/26/2023 2:17 PM, Adrian Mariano wrote:
>> > In the case of hull, you write hull(){x;y;z} and the union is
>> > unnecessarily computed and then passed to hull(). This is bad because
>> > hull() is fast whereas union can be very slow, so your code can be 10x
>> > faster with lazy union. If I recall correctly, the common strategy of
>> > making a rounded cube by doing the hull of 8 spheres is dramatically
>> > faster if you have lazy unions.
>>
>> I think the semantics change with lazy union is much more important than
>> performance associated to lazy union. Performance with this is just an
>> implementation issue.
>>
>> 1. With manifold backend enabled, hull + union of 8 *intersecting*
>> spheres (i.e. cannot skip union on manifold side) with $fn=256
>> took 1.7s, while hull without union took 1s, which is not dramatically
>> faster...
>>
>> 2. We can always optimize hull + union *without affecting semantics*. We
>> already have a bunch of CSG tree rewriting rules for optimization in
>> manifold, it is quite trivial to extend them to hull.
>>
>> I think the name for lazy-union is simply wrong. Laziness will not
>> change the semantics of a pure functional programming language.
>> Lazy-union should be renamed into implicit union, which is the real
>> breaking change. The ability to use for expression to generate a bunch
>> of stuff and intersect them together is an important usecase, and is
>> currently impossible to do without 'lazy-union'.
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
NH
nop head
Wed, Sep 27, 2023 9:57 AM
Lazy union enables a for loop to generate multiple children so if you pass
the result to a module that uses children() it can index them individually.
Similarly it lets a module return multiple children so they can be indexed.
It is a semantic change, but not just for performance.
On Wed, 27 Sept 2023 at 10:51, pca006132 john.lck40@gmail.com wrote:
If it does not enable more things, and it causes semantics change, should
we remove it? It seems to me that there is no reason to keep it. We can use
some other methods to get better performance without changing the behavior
of existing code.
On Wed, Sep 27, 2023, 5:24 PM nop head nop.head@gmail.com wrote:
There is intersection_for, so it isn't impossible.
On Wed, 27 Sept 2023, 10:21 Chun Kit LAM, john.lck40@gmail.com wrote:
On 9/26/2023 2:17 PM, Adrian Mariano wrote:
In the case of hull, you write hull(){x;y;z} and the union is
unnecessarily computed and then passed to hull(). This is bad because
hull() is fast whereas union can be very slow, so your code can be 10x
faster with lazy union. If I recall correctly, the common strategy of
making a rounded cube by doing the hull of 8 spheres is dramatically
faster if you have lazy unions.
I think the semantics change with lazy union is much more important than
performance associated to lazy union. Performance with this is just an
implementation issue.
-
With manifold backend enabled, hull + union of 8 intersecting
spheres (i.e. cannot skip union on manifold side) with $fn=256
took 1.7s, while hull without union took 1s, which is not dramatically
faster...
-
We can always optimize hull + union without affecting semantics. We
already have a bunch of CSG tree rewriting rules for optimization in
manifold, it is quite trivial to extend them to hull.
I think the name for lazy-union is simply wrong. Laziness will not
change the semantics of a pure functional programming language.
Lazy-union should be renamed into implicit union, which is the real
breaking change. The ability to use for expression to generate a bunch
of stuff and intersect them together is an important usecase, and is
currently impossible to do without 'lazy-union'.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Lazy union enables a for loop to generate multiple children so if you pass
the result to a module that uses children() it can index them individually.
Similarly it lets a module return multiple children so they can be indexed.
It is a semantic change, but not just for performance.
On Wed, 27 Sept 2023 at 10:51, pca006132 <john.lck40@gmail.com> wrote:
> If it does not enable more things, and it causes semantics change, should
> we remove it? It seems to me that there is no reason to keep it. We can use
> some other methods to get better performance without changing the behavior
> of existing code.
>
> On Wed, Sep 27, 2023, 5:24 PM nop head <nop.head@gmail.com> wrote:
>
>> There is intersection_for, so it isn't impossible.
>>
>> On Wed, 27 Sept 2023, 10:21 Chun Kit LAM, <john.lck40@gmail.com> wrote:
>>
>>> On 9/26/2023 2:17 PM, Adrian Mariano wrote:
>>> > In the case of hull, you write hull(){x;y;z} and the union is
>>> > unnecessarily computed and then passed to hull(). This is bad because
>>> > hull() is fast whereas union can be very slow, so your code can be 10x
>>> > faster with lazy union. If I recall correctly, the common strategy of
>>> > making a rounded cube by doing the hull of 8 spheres is dramatically
>>> > faster if you have lazy unions.
>>>
>>> I think the semantics change with lazy union is much more important than
>>> performance associated to lazy union. Performance with this is just an
>>> implementation issue.
>>>
>>> 1. With manifold backend enabled, hull + union of 8 *intersecting*
>>> spheres (i.e. cannot skip union on manifold side) with $fn=256
>>> took 1.7s, while hull without union took 1s, which is not dramatically
>>> faster...
>>>
>>> 2. We can always optimize hull + union *without affecting semantics*. We
>>> already have a bunch of CSG tree rewriting rules for optimization in
>>> manifold, it is quite trivial to extend them to hull.
>>>
>>> I think the name for lazy-union is simply wrong. Laziness will not
>>> change the semantics of a pure functional programming language.
>>> Lazy-union should be renamed into implicit union, which is the real
>>> breaking change. The ability to use for expression to generate a bunch
>>> of stuff and intersect them together is an important usecase, and is
>>> currently impossible to do without 'lazy-union'.
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>>
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
MA
Martin Axelsen
Wed, Sep 27, 2023 11:07 AM
Speaking of which...
To me creating an extrude_for() seems quite impossible.
Or is this a totally different thing?
Martin
On Wed, Sep 27, 2023, 11:24 nop head nop.head@gmail.com wrote:
There is intersection_for, so it isn't impossible.
On Wed, 27 Sept 2023, 10:21 Chun Kit LAM, john.lck40@gmail.com wrote:
On 9/26/2023 2:17 PM, Adrian Mariano wrote:
In the case of hull, you write hull(){x;y;z} and the union is
unnecessarily computed and then passed to hull(). This is bad because
hull() is fast whereas union can be very slow, so your code can be 10x
faster with lazy union. If I recall correctly, the common strategy of
making a rounded cube by doing the hull of 8 spheres is dramatically
faster if you have lazy unions.
I think the semantics change with lazy union is much more important than
performance associated to lazy union. Performance with this is just an
implementation issue.
-
With manifold backend enabled, hull + union of 8 intersecting
spheres (i.e. cannot skip union on manifold side) with $fn=256
took 1.7s, while hull without union took 1s, which is not dramatically
faster...
-
We can always optimize hull + union without affecting semantics. We
already have a bunch of CSG tree rewriting rules for optimization in
manifold, it is quite trivial to extend them to hull.
I think the name for lazy-union is simply wrong. Laziness will not
change the semantics of a pure functional programming language.
Lazy-union should be renamed into implicit union, which is the real
breaking change. The ability to use for expression to generate a bunch
of stuff and intersect them together is an important usecase, and is
currently impossible to do without 'lazy-union'.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Speaking of which...
To me creating an extrude_for() seems quite impossible.
Or is this a totally different thing?
Martin
On Wed, Sep 27, 2023, 11:24 nop head <nop.head@gmail.com> wrote:
> There is intersection_for, so it isn't impossible.
>
> On Wed, 27 Sept 2023, 10:21 Chun Kit LAM, <john.lck40@gmail.com> wrote:
>
>> On 9/26/2023 2:17 PM, Adrian Mariano wrote:
>> > In the case of hull, you write hull(){x;y;z} and the union is
>> > unnecessarily computed and then passed to hull(). This is bad because
>> > hull() is fast whereas union can be very slow, so your code can be 10x
>> > faster with lazy union. If I recall correctly, the common strategy of
>> > making a rounded cube by doing the hull of 8 spheres is dramatically
>> > faster if you have lazy unions.
>>
>> I think the semantics change with lazy union is much more important than
>> performance associated to lazy union. Performance with this is just an
>> implementation issue.
>>
>> 1. With manifold backend enabled, hull + union of 8 *intersecting*
>> spheres (i.e. cannot skip union on manifold side) with $fn=256
>> took 1.7s, while hull without union took 1s, which is not dramatically
>> faster...
>>
>> 2. We can always optimize hull + union *without affecting semantics*. We
>> already have a bunch of CSG tree rewriting rules for optimization in
>> manifold, it is quite trivial to extend them to hull.
>>
>> I think the name for lazy-union is simply wrong. Laziness will not
>> change the semantics of a pure functional programming language.
>> Lazy-union should be renamed into implicit union, which is the real
>> breaking change. The ability to use for expression to generate a bunch
>> of stuff and intersect them together is an important usecase, and is
>> currently impossible to do without 'lazy-union'.
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
AM
Adrian Mariano
Wed, Sep 27, 2023 11:08 AM
Wow, manifold really makes a huge difference here. I am not sure what you
are intending to demonstrate with your timing example. If union is always
required then lazy union won't be much help. My findings are below: lazy
union makes disjoint hull 6x faster in this case. That's significant, but
not nearly as big of an improvement as the situation with manifold turned
off. But I'd like to have my model preview 1 minute instead of 6 minutes,
so performance remains an issue.
$fn=256;
module rcube(r)
hull(){for(i=[0:1],j=[0:1],k=[0:1]) translate([i,j,k]) sphere(r=r);}
rcube(.3);
// Manifold off, lazy union off: preview in 3:08 (yes, 3 minutes)
// Manifold off, lazy union on: preview in 0.281
// Manifold on, lazy union off: preview in 1.597
// Manifold on, lazy union on: preview in 0.269
// Lazy union without manifold, 118x speed increase
// Lazy union with manifold, 6x speed increase
Regarding the semantic change, River wrote code to do xor() of children.
With lazy union---which should indeed be called implicit union---this could
be fully general and would be a short recursive code. With out implicit
unions, it's impossible to make fully general and you have to special case
handle every different number of children that you want to have work
because you can't write the recursive method---if you try, it unions all
the children.
module exclusive_or() {
if ($children==1) {
children();
} else if ($children==2) {
difference() {
children(0);
children(1);
}
difference() {
children(1);
children(0);
}
} else if ($children==3) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
}
children(2);
}
} else if ($children==4) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
}
exclusive_or() {
children(2);
children(3);
}
}
} else if ($children==5) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
children(4);
}
} else if ($children==6) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
children(4);
children(5);
}
} else if ($children==7) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
children(4);
children(5);
children(6);
}
} else if ($children==8) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
exclusive_or() {
children(4);
children(5);
children(6);
children(7);
}
}
} else if ($children==9) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
exclusive_or() {
children(4);
children(5);
children(6);
children(7);
}
children(8);
}
} else if ($children==10) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
exclusive_or() {
children(4);
children(5);
children(6);
children(7);
}
children(8);
children(9);
}
} else {
assert($children<=10, "exclusive_or() can only handle up to 10
children.");
}
}
On Wed, Sep 27, 2023 at 4:05 AM Chun Kit LAM john.lck40@gmail.com wrote:
On 9/26/2023 2:17 PM, Adrian Mariano wrote:
In the case of hull, you write hull(){x;y;z} and the union is
unnecessarily computed and then passed to hull(). This is bad because
hull() is fast whereas union can be very slow, so your code can be 10x
faster with lazy union. If I recall correctly, the common strategy of
making a rounded cube by doing the hull of 8 spheres is dramatically
faster if you have lazy unions.
I think the semantics change with lazy union is much more important than
performance associated to lazy union. Performance with this is just an
implementation issue.
-
With manifold backend enabled, hull + union of 8 intersecting
spheres (i.e. cannot skip union on manifold side) with $fn=256
took 1.7s, while hull without union took 1s, which is not dramatically
faster...
-
We can always optimize hull + union without affecting semantics. We
already have a bunch of CSG tree rewriting rules for optimization in
manifold, it is quite trivial to extend them to hull.
I think the name for lazy-union is simply wrong. Laziness will not
change the semantics of a pure functional programming language.
Lazy-union should be renamed into implicit union, which is the real
breaking change. The ability to use for expression to generate a bunch
of stuff and intersect them together is an important usecase, and is
currently impossible to do without 'lazy-union'.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Wow, manifold really makes a huge difference here. I am not sure what you
are intending to demonstrate with your timing example. If union is always
required then lazy union won't be much help. My findings are below: lazy
union makes disjoint hull 6x faster in this case. That's significant, but
not nearly as big of an improvement as the situation with manifold turned
off. But I'd like to have my model preview 1 minute instead of 6 minutes,
so performance remains an issue.
$fn=256;
module rcube(r)
hull(){for(i=[0:1],j=[0:1],k=[0:1]) translate([i,j,k]) sphere(r=r);}
rcube(.3);
// Manifold off, lazy union off: preview in 3:08 (yes, 3 minutes)
// Manifold off, lazy union on: preview in 0.281
// Manifold on, lazy union off: preview in 1.597
// Manifold on, lazy union on: preview in 0.269
// Lazy union without manifold, 118x speed increase
// Lazy union with manifold, 6x speed increase
--------------------------------------------------------------------------------
Regarding the semantic change, River wrote code to do xor() of children.
With lazy union---which should indeed be called implicit union---this could
be fully general and would be a short recursive code. With out implicit
unions, it's impossible to make fully general and you have to special case
handle every different number of children that you want to have work
because you can't write the recursive method---if you try, it unions all
the children.
module exclusive_or() {
if ($children==1) {
children();
} else if ($children==2) {
difference() {
children(0);
children(1);
}
difference() {
children(1);
children(0);
}
} else if ($children==3) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
}
children(2);
}
} else if ($children==4) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
}
exclusive_or() {
children(2);
children(3);
}
}
} else if ($children==5) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
children(4);
}
} else if ($children==6) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
children(4);
children(5);
}
} else if ($children==7) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
children(4);
children(5);
children(6);
}
} else if ($children==8) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
exclusive_or() {
children(4);
children(5);
children(6);
children(7);
}
}
} else if ($children==9) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
exclusive_or() {
children(4);
children(5);
children(6);
children(7);
}
children(8);
}
} else if ($children==10) {
exclusive_or() {
exclusive_or() {
children(0);
children(1);
children(2);
children(3);
}
exclusive_or() {
children(4);
children(5);
children(6);
children(7);
}
children(8);
children(9);
}
} else {
assert($children<=10, "exclusive_or() can only handle up to 10
children.");
}
}
On Wed, Sep 27, 2023 at 4:05 AM Chun Kit LAM <john.lck40@gmail.com> wrote:
> On 9/26/2023 2:17 PM, Adrian Mariano wrote:
> > In the case of hull, you write hull(){x;y;z} and the union is
> > unnecessarily computed and then passed to hull(). This is bad because
> > hull() is fast whereas union can be very slow, so your code can be 10x
> > faster with lazy union. If I recall correctly, the common strategy of
> > making a rounded cube by doing the hull of 8 spheres is dramatically
> > faster if you have lazy unions.
>
> I think the semantics change with lazy union is much more important than
> performance associated to lazy union. Performance with this is just an
> implementation issue.
>
> 1. With manifold backend enabled, hull + union of 8 *intersecting*
> spheres (i.e. cannot skip union on manifold side) with $fn=256
> took 1.7s, while hull without union took 1s, which is not dramatically
> faster...
>
> 2. We can always optimize hull + union *without affecting semantics*. We
> already have a bunch of CSG tree rewriting rules for optimization in
> manifold, it is quite trivial to extend them to hull.
>
> I think the name for lazy-union is simply wrong. Laziness will not
> change the semantics of a pure functional programming language.
> Lazy-union should be renamed into implicit union, which is the real
> breaking change. The ability to use for expression to generate a bunch
> of stuff and intersect them together is an important usecase, and is
> currently impossible to do without 'lazy-union'.
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>